diff --git a/code/__defines/admin.dm b/code/__defines/admin.dm index 5f9ada5e98..d2afb7846e 100644 --- a/code/__defines/admin.dm +++ b/code/__defines/admin.dm @@ -39,4 +39,9 @@ #define R_EVENT 0x4000 #define R_HOST 0x8000 //higher than this will overflow -#define R_MAXPERMISSION 0x8000 // This holds the maximum value for a permission. It is used in iteration, so keep it updated. \ No newline at end of file +#define R_MAXPERMISSION 0x8000 // This holds the maximum value for a permission. It is used in iteration, so keep it updated. + +#define SMITE_BREAKLEGS "Break Legs" +#define SMITE_BLUESPACEARTILLERY "Bluespace Artillery" +#define SMITE_SPONTANEOUSCOMBUSTION "Spontaneous Combustion" +#define SMITE_LIGHTNINGBOLT "Lightning Bolt" diff --git a/code/__defines/admin_vr.dm b/code/__defines/admin_vr.dm new file mode 100644 index 0000000000..6e5e8c1a9b --- /dev/null +++ b/code/__defines/admin_vr.dm @@ -0,0 +1,3 @@ +#define SMITE_SHADEKIN_ATTACK "Shadekin (Attack)" +#define SMITE_SHADEKIN_NOMF "Shadekin (Devour)" +#define SMITE_REDSPACE_ABDUCT "Redspace Abduction" diff --git a/code/_onclick/adjacent.dm b/code/_onclick/adjacent.dm index 47e7e99a92..25997f90ed 100644 --- a/code/_onclick/adjacent.dm +++ b/code/_onclick/adjacent.dm @@ -31,7 +31,7 @@ return 1 if(get_dist(src,T0) > 1) return 0 - + if(T0.z != z) return 0 //VOREStation Add if(T0.x == x || T0.y == y) // Check for border blockages return T0.ClickCross(get_dir(T0,src), border_only = 1) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target) diff --git a/code/game/turfs/unsimulated.dm b/code/game/turfs/unsimulated.dm index cbf492b081..b4c1999b48 100644 --- a/code/game/turfs/unsimulated.dm +++ b/code/game/turfs/unsimulated.dm @@ -3,3 +3,15 @@ oxygen = MOLES_O2STANDARD nitrogen = MOLES_N2STANDARD initialized = TRUE // Don't call init on unsimulated turfs (at least not yet) + +//VOREStation Add +/turf/unsimulated/fake_space + name = "\proper space" + icon = 'icons/turf/space.dmi' + icon_state = "0" + dynamic_lighting = FALSE + +/turf/unsimulated/fake_space/New() + ..() + icon_state = "[((x + y) ^ ~(x * y) + z) % 25]" +//VOREStation Add End \ No newline at end of file diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 59a787a2ae..9a0a0ce87d 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -134,7 +134,9 @@ var/list/admin_verbs_fun = list( /client/proc/editappear, /client/proc/roll_dices, /datum/admins/proc/call_supply_drop, - /datum/admins/proc/call_drop_pod + /datum/admins/proc/call_drop_pod, + /client/proc/smite_vr, //VOREStation Add, + /client/proc/smite ) var/list/admin_verbs_spawn = list( diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 704be1e117..f92bae98fb 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1325,6 +1325,16 @@ feedback_inc("admin_cookies_spawned",1) H << "Your prayers have been answered!! You received the best cookie!" + else if(href_list["adminsmite"]) + if(!check_rights(R_ADMIN|R_FUN)) return + + var/mob/living/carbon/human/H = locate(href_list["adminsmite"]) + if(!ishuman(H)) + usr << "This can only be used on instances of type /mob/living/carbon/human" + return + + owner.smite(H) + else if(href_list["BlueSpaceArtillery"]) if(!check_rights(R_ADMIN|R_FUN)) return @@ -1336,37 +1346,7 @@ if(alert(src.owner, "Are you sure you wish to hit [key_name(M)] with Blue Space Artillery?", "Confirm Firing?" , "Yes" , "No") != "Yes") return - if(BSACooldown) - src.owner << "Standby! Reload cycle in progress! Gunnary crews ready in five seconds!" - return - - BSACooldown = 1 - spawn(50) - BSACooldown = 0 - - M << "You've been hit by bluespace artillery!" - log_admin("[key_name(M)] has been hit by Bluespace Artillery fired by [src.owner]") - message_admins("[key_name(M)] has been hit by Bluespace Artillery fired by [src.owner]") - - var/obj/effect/stop/S - S = new /obj/effect/stop - S.victim = M - S.loc = M.loc - spawn(20) - qdel(S) - - var/turf/simulated/floor/T = get_turf(M) - if(istype(T)) - if(prob(80)) T.break_tile_to_plating() - else T.break_tile() - - if(M.health == 1) - M.gib() - else - M.adjustBruteLoss( min( 99 , (M.health - 1) ) ) - M.Stun(20) - M.Weaken(20) - M.stuttering = 20 + bluespace_artillery(M,src) else if(href_list["CentComReply"]) var/mob/living/L = locate(href_list["CentComReply"]) diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index b8fbf77ed3..5469367beb 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -17,7 +17,7 @@ return var/image/cross = image('icons/obj/storage.dmi',"bible") - msg = "\icon[cross] PRAY: [key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src, src)]) (CA) (SC): [msg]" + msg = "\icon[cross] PRAY: [key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src, src)]) (CA) (SC) (SMITE): [msg]" for(var/client/C in admins) if(R_ADMIN & C.holder.rights) diff --git a/code/modules/admin/verbs/smite.dm b/code/modules/admin/verbs/smite.dm new file mode 100644 index 0000000000..e8183e3665 --- /dev/null +++ b/code/modules/admin/verbs/smite.dm @@ -0,0 +1,83 @@ +/client/proc/smite(var/mob/living/carbon/human/target in player_list) + set name = "Smite" + set desc = "Abuse a player with various 'special treatments' from a list." + set category = "Fun" + if(!check_rights(R_FUN)) + return + + if(!istype(target)) + return + + var/list/smite_types = list(SMITE_BREAKLEGS,SMITE_BLUESPACEARTILLERY,SMITE_SPONTANEOUSCOMBUSTION,SMITE_LIGHTNINGBOLT) + + var/smite_choice = input("Select the type of SMITE for [target]","SMITE Type Choice") as null|anything in smite_types + if(!smite_choice) + return + + switch(smite_choice) + if(SMITE_BREAKLEGS) + var/broken_legs = 0 + var/obj/item/organ/external/left_leg = target.get_organ(BP_L_LEG) + if(left_leg && left_leg.fracture()) + broken_legs++ + var/obj/item/organ/external/right_leg = target.get_organ(BP_R_LEG) + if(right_leg && right_leg.fracture()) + broken_legs++ + if(!broken_legs) + to_chat(src,"[target] didn't have any breakable legs, sorry.") + + if(SMITE_BLUESPACEARTILLERY) + bluespace_artillery(target,src) + + if(SMITE_SPONTANEOUSCOMBUSTION) + target.adjust_fire_stacks(10) + target.IgniteMob() + target.visible_message("[target] bursts into flames!") + + if(SMITE_LIGHTNINGBOLT) + var/turf/T = get_step(get_step(target, NORTH), NORTH) + T.Beam(target, icon_state="lightning[rand(1,12)]", time = 5) + target.electrocute_act(75,def_zone = BP_HEAD) + target.visible_message("[target] is struck by lightning!") + + else + return //Injection? Don't print any messages. + + log_and_message_admins("[key_name(src)] has used SMITE ([smite_choice]) on [key_name(target)].") + feedback_add_details("admin_verb","SMITE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/proc/bluespace_artillery(mob/living/target, user) + if(!istype(target)) + return + + if(BSACooldown) + if(user) + to_chat(user,"BSA is still cooling down, please wait!") + return + + BSACooldown = 1 + spawn(50) + BSACooldown = 0 + + to_chat(target,"You've been hit by bluespace artillery!") + log_and_message_admins("[key_name(target)] has been hit by Bluespace Artillery fired by [key_name(user ? user : usr)]") + + var/obj/effect/stop/S + S = new /obj/effect/stop + S.victim = target + S.loc = target.loc + spawn(20) + qdel(S) + + var/turf/simulated/floor/T = get_turf(target) + if(istype(T)) + if(prob(80)) T.break_tile_to_plating() + else T.break_tile() + + if(target.health == 1) + target.gib() + else + target.adjustBruteLoss( min( 99 , (target.health - 1) ) ) + target.Stun(20) + target.Weaken(20) + target.stuttering = 20 diff --git a/code/modules/admin/verbs/smite_vr.dm b/code/modules/admin/verbs/smite_vr.dm new file mode 100644 index 0000000000..6fccc23dfa --- /dev/null +++ b/code/modules/admin/verbs/smite_vr.dm @@ -0,0 +1,211 @@ +/client/proc/smite_vr(var/mob/living/carbon/human/target in player_list) + set name = "Smite (Vore)" + set desc = "Abuse a player with various 'special Vore-brand treatments' from a list." + set category = "Fun" + if(!check_rights(R_ADMIN|R_FUN)) + return + + if(!istype(target)) + return + + var/list/smite_types = list(SMITE_SHADEKIN_ATTACK,SMITE_SHADEKIN_NOMF,SMITE_REDSPACE_ABDUCT) + + var/smite_choice = input("Select the type of SMITE for [target]","SMITE Type Choice") as null|anything in smite_types + if(!smite_choice) + return + + log_and_message_admins("[key_name(src)] has used SMITE (Vore) ([smite_choice]) on [key_name(target)].") + feedback_add_details("admin_verb","SMITEV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + switch(smite_choice) + if(SMITE_SHADEKIN_ATTACK) + var/turf/Tt = get_turf(target) //Turf for target + + if(target.loc != Tt) + return //Too hard to attack someone in something + + var/turf/Ts //Turf for shadekin + + //Try to find nondense turf + for(var/direction in cardinal) + var/turf/T = get_step(target,direction) + if(T && !T.density) + Ts = T //Found shadekin spawn turf + if(!Ts) + return //Didn't find shadekin spawn turf + + var/mob/living/simple_animal/shadekin/red/shadekin = new(Ts) + //Abuse of shadekin + shadekin.real_name = shadekin.name + shadekin.init_vore() + shadekin.ability_flags |= 0x1 + shadekin.specific_targets = TRUE //Don't attack others + shadekin.phase_shift() + shadekin.target_mob = target + shadekin.stance = STANCE_ATTACK + shadekin.Life() + //Remove when done + spawn(10 SECONDS) + if(shadekin) + shadekin.death() + + if(SMITE_SHADEKIN_NOMF) + var/list/kin_types = list( + "Red Eyes (Dark)" = /mob/living/simple_animal/shadekin/red/dark, + "Red Eyes (Light)" = /mob/living/simple_animal/shadekin/red/white, + "Red Eyes (Brown)" = /mob/living/simple_animal/shadekin/red/brown, + "Blue Eyes (Dark)" = /mob/living/simple_animal/shadekin/blue/dark, + "Blue Eyes (Light)" = /mob/living/simple_animal/shadekin/blue/white, + "Blue Eyes (Brown)" = /mob/living/simple_animal/shadekin/blue/brown, + "Purple Eyes (Dark)" = /mob/living/simple_animal/shadekin/purple/dark, + "Purple Eyes (Light)" = /mob/living/simple_animal/shadekin/purple/white, + "Purple Eyes (Brown)" = /mob/living/simple_animal/shadekin/purple/brown, + "Yellow Eyes (Dark)" = /mob/living/simple_animal/shadekin/yellow/dark, + "Yellow Eyes (Light)" = /mob/living/simple_animal/shadekin/yellow/white, + "Yellow Eyes (Brown)" = /mob/living/simple_animal/shadekin/yellow/brown, + "Green Eyes (Dark)" = /mob/living/simple_animal/shadekin/green/dark, + "Green Eyes (Light)" = /mob/living/simple_animal/shadekin/green/white, + "Green Eyes (Brown)" = /mob/living/simple_animal/shadekin/green/brown, + "Orange Eyes (Dark)" = /mob/living/simple_animal/shadekin/orange/dark, + "Orange Eyes (Light)" = /mob/living/simple_animal/shadekin/orange/white, + "Orange Eyes (Brown)" = /mob/living/simple_animal/shadekin/orange/brown, + "Rivyr (Unique)" = /mob/living/simple_animal/shadekin/blue/rivyr) + var/kin_type = input("Select the type of shadekin for [target] nomf","Shadekin Type Choice") as null|anything in kin_types + if(!kin_type || !target) + return + + kin_type = kin_types[kin_type] + + var/myself = alert("Control the shadekin yourself or delete pred and prey after?","Control Shadekin?","Control","Cancel","Delete") + if(myself == "Cancel" || !target) + return + + var/turf/Tt = get_turf(target) + + if(target.loc != Tt) + return //Can't nom when not exposed + + //Begin abuse + target.transforming = TRUE //Cheap hack to stop them from moving + var/mob/living/simple_animal/shadekin/shadekin = new kin_type(Tt) + shadekin.real_name = shadekin.name + shadekin.init_vore() + shadekin.can_be_drop_pred = TRUE + shadekin.ai_inactive = TRUE + shadekin.dir = SOUTH + shadekin.ability_flags |= 0x1 + shadekin.phase_shift() //Homf + shadekin.energy = initial(shadekin.energy) + //For fun + sleep(1 SECOND) + shadekin.dir = WEST + sleep(1 SECOND) + shadekin.dir = EAST + sleep(1 SECOND) + shadekin.dir = SOUTH + sleep(1 SECOND) + shadekin.audible_message("[shadekin] belches loudly!") + sleep(2 SECONDS) + shadekin.phase_shift() + target.transforming = FALSE //Undo cheap hack + + if(myself == "Control") //Put admin in mob + shadekin.ckey = ckey + + else //Permakin'd + to_chat(target,"You're carried off into The Dark by the [shadekin]. Who knows if you'll find your way back?") + target.ghostize() + qdel(target) + qdel(shadekin) + + if(SMITE_REDSPACE_ABDUCT) + redspace_abduction(target, src) + + else + return //Injection? Don't print any messages. + +var/redspace_abduction_z + +/area/redspace_abduction + name = "Another Time And Place" + requires_power = FALSE + dynamic_lighting = FALSE + +/proc/redspace_abduction(mob/living/target, user) + if(redspace_abduction_z < 0) + to_chat(user,"The abduction z-level is already being created. Please wait.") + return + if(!redspace_abduction_z) + redspace_abduction_z = -1 + to_chat(user,"This is the first use of the verb this shift, it will take a minute to configure the abduction z-level. It will be z[world.maxz+1].") + var/z = ++world.maxz + for(var/x = 1 to world.maxx) + for(var/y = 1 to world.maxy) + var/turf/T = locate(x,y,z) + new /area/redspace_abduction(T) + T.ChangeTurf(/turf/unsimulated/fake_space) + CHECK_TICK + redspace_abduction_z = z + + if(!target || !user) + return + + var/size_of_square = 26 + var/halfbox = round(size_of_square*0.5) + target.transforming = TRUE + to_chat(target,"You feel a strange tug, deep inside. You're frozen in momentarily...") + to_chat(user,"Beginning vis_contents copy to abduction site, player mob is frozen.") + sleep(1 SECOND) + //Lower left corner of a working box + var/llc_x = max(0,halfbox-target.x) + min(target.x+halfbox, world.maxx) - size_of_square + var/llc_y = max(0,halfbox-target.y) + min(target.y+halfbox, world.maxy) - size_of_square + + //Copy them all + for(var/x = llc_x to llc_x+size_of_square) + for(var/y = llc_y to llc_y+size_of_square) + var/turf/T_src = locate(x,y,target.z) + var/turf/T_dest = locate(x,y,redspace_abduction_z) + T_dest.vis_contents.Cut() + T_dest.vis_contents += T_src + T_dest.density = T_src.density + T_dest.opacity = T_src.opacity + CHECK_TICK + + //Feather the edges + for(var/x = llc_x to llc_x+1) //Left + for(var/y = llc_y to llc_y+size_of_square) + if(prob(50)) + var/turf/T = locate(x,y,redspace_abduction_z) + T.density = FALSE + T.opacity = FALSE + T.vis_contents.Cut() + + for(var/x = llc_x+size_of_square-1 to llc_x+size_of_square) //Right + for(var/y = llc_y to llc_y+size_of_square) + if(prob(50)) + var/turf/T = locate(x,y,redspace_abduction_z) + T.density = FALSE + T.opacity = FALSE + T.vis_contents.Cut() + + for(var/x = llc_x to llc_x+size_of_square) //Top + for(var/y = llc_y+size_of_square-1 to llc_y+size_of_square) + if(prob(50)) + var/turf/T = locate(x,y,redspace_abduction_z) + T.density = FALSE + T.opacity = FALSE + T.vis_contents.Cut() + + for(var/x = llc_x to llc_x+size_of_square) //Bottom + for(var/y = llc_y to llc_y+1) + if(prob(50)) + var/turf/T = locate(x,y,redspace_abduction_z) + T.density = FALSE + T.opacity = FALSE + T.vis_contents.Cut() + + target.forceMove(locate(target.x,target.y,redspace_abduction_z)) + to_chat(target,"The tug relaxes, but everything around you looks... slightly off.") + to_chat(user,"The mob has been moved. ([admin_jump_link(target,usr.client.holder)])") + + target.transforming = FALSE diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 9d16617a67..5d176026f2 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -1050,6 +1050,8 @@ Note that amputating the affected organ does in fact remove the infection from t var/obj/item/clothing/suit/space/suit = owner.wear_suit suit.handle_fracture(owner, src) + return 1 + /obj/item/organ/external/proc/mend_fracture() if(robotic >= ORGAN_ROBOT) return 0 //ORGAN_BROKEN doesn't have the same meaning for robot limbs diff --git a/vorestation.dme b/vorestation.dme index 4708e10d2c..b1c402130e 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -26,6 +26,7 @@ #include "code\__defines\_planes+layers_vr.dm" #include "code\__defines\_tick.dm" #include "code\__defines\admin.dm" +#include "code\__defines\admin_vr.dm" #include "code\__defines\appearance.dm" #include "code\__defines\atmos.dm" #include "code\__defines\belly_modes_vr.dm" @@ -1381,6 +1382,8 @@ #include "code\modules\admin\verbs\SDQL.dm" #include "code\modules\admin\verbs\SDQL_2.dm" #include "code\modules\admin\verbs\SDQL_2_parser.dm" +#include "code\modules\admin\verbs\smite.dm" +#include "code\modules\admin\verbs\smite_vr.dm" #include "code\modules\admin\verbs\striketeam.dm" #include "code\modules\admin\verbs\ticklag.dm" #include "code\modules\admin\verbs\tripAI.dm"