Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit28
This commit is contained in:
@@ -274,8 +274,7 @@
|
||||
/area/ruin/powered/seedvault)
|
||||
"Z" = (
|
||||
/obj/item/disk/design_disk/plant_disk,
|
||||
/obj/machinery/autolathe{
|
||||
hacked = TRUE;
|
||||
/obj/machinery/autolathe/hacked{
|
||||
desc = "This autolathe seems to have its safety light off."
|
||||
},
|
||||
/turf/open/floor/plasteel/freezer,
|
||||
|
||||
@@ -913,6 +913,10 @@
|
||||
},
|
||||
/turf/open/indestructible/paper,
|
||||
/area/ruin/powered)
|
||||
"Ns" = (
|
||||
/obj/item/paper/secretrecipe,
|
||||
/turf/open/indestructible/paper,
|
||||
/area/ruin/powered)
|
||||
|
||||
(1,1,1) = {"
|
||||
aa
|
||||
@@ -2247,7 +2251,7 @@ ap
|
||||
az
|
||||
af
|
||||
al
|
||||
aA
|
||||
Ns
|
||||
bW
|
||||
ca
|
||||
af
|
||||
|
||||
2941
_maps/RandomRuins/SpaceRuins/spacehermit.dmm
Normal file
2941
_maps/RandomRuins/SpaceRuins/spacehermit.dmm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -515,10 +515,13 @@
|
||||
/turf/closed/wall,
|
||||
/area/security/main)
|
||||
"abq" = (
|
||||
/turf/closed/wall,
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/crew_quarters/heads/hos)
|
||||
"abr" = (
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/obj/machinery/door/poddoor/preopen{
|
||||
id = "hos"
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/crew_quarters/heads/hos)
|
||||
"abs" = (
|
||||
@@ -846,8 +849,13 @@
|
||||
},
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/reagent_containers/food/drinks/bottle/vodka/badminka,
|
||||
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
|
||||
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
|
||||
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass{
|
||||
pixel_x = -5;
|
||||
pixel_y = 5
|
||||
},
|
||||
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass{
|
||||
pixel_x = -5
|
||||
},
|
||||
/turf/open/floor/carpet,
|
||||
/area/crew_quarters/heads/hos)
|
||||
"abX" = (
|
||||
@@ -1449,6 +1457,9 @@
|
||||
"adm" = (
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/obj/machinery/door/poddoor/preopen{
|
||||
id = "hos"
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/crew_quarters/heads/hos)
|
||||
"adn" = (
|
||||
@@ -1673,6 +1684,12 @@
|
||||
"adM" = (
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/button/door{
|
||||
id = "hos";
|
||||
name = "HoS Office Shutters";
|
||||
pixel_y = -25;
|
||||
|
||||
},
|
||||
/turf/open/floor/carpet,
|
||||
/area/crew_quarters/heads/hos)
|
||||
@@ -2053,6 +2070,9 @@
|
||||
"aex" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/obj/machinery/door/poddoor/preopen{
|
||||
id = "hos"
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/crew_quarters/heads/hos)
|
||||
"aey" = (
|
||||
@@ -11691,7 +11711,7 @@
|
||||
/area/maintenance/port/fore)
|
||||
"aAW" = (
|
||||
/obj/structure/rack,
|
||||
/obj/item/tank/jetpack/carbondioxide,
|
||||
/obj/item/tank/jetpack/carbondioxide/eva,
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
@@ -11815,7 +11835,7 @@
|
||||
/obj/machinery/light{
|
||||
dir = 8
|
||||
},
|
||||
/obj/item/tank/jetpack/carbondioxide,
|
||||
/obj/item/tank/jetpack/carbondioxide/eva,
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
@@ -56882,12 +56902,6 @@
|
||||
/obj/item/pen,
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/circuit)
|
||||
"ium" = (
|
||||
/mob/living/simple_animal/bot/cleanbot{
|
||||
name = "C.L.E.A.N."
|
||||
},
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/medical/medbay/central)
|
||||
"izv" = (
|
||||
/obj/machinery/vending/clothing,
|
||||
/obj/machinery/light/small{
|
||||
@@ -57122,6 +57136,12 @@
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/construction/mining/aux_base)
|
||||
"lKX" = (
|
||||
/mob/living/simple_animal/bot/cleanbot{
|
||||
name = "C.L.E.A.N."
|
||||
},
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/medical/medbay/central)
|
||||
"lMg" = (
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 9
|
||||
@@ -88468,7 +88488,7 @@ aaa
|
||||
aaf
|
||||
aaf
|
||||
aaa
|
||||
abp
|
||||
adR
|
||||
abP
|
||||
aco
|
||||
acO
|
||||
@@ -88982,7 +89002,7 @@ aaa
|
||||
aaa
|
||||
aaf
|
||||
aaa
|
||||
abp
|
||||
adR
|
||||
abO
|
||||
acq
|
||||
acq
|
||||
@@ -89496,15 +89516,15 @@ aaa
|
||||
aaa
|
||||
aaa
|
||||
aaf
|
||||
abp
|
||||
adR
|
||||
abR
|
||||
abP
|
||||
abP
|
||||
abP
|
||||
abP
|
||||
abp
|
||||
abp
|
||||
abp
|
||||
adR
|
||||
adR
|
||||
adR
|
||||
agA
|
||||
afU
|
||||
ahF
|
||||
@@ -94188,7 +94208,7 @@ blm
|
||||
bmL
|
||||
boi
|
||||
bpw
|
||||
ium
|
||||
lKX
|
||||
bsx
|
||||
btX
|
||||
bvj
|
||||
|
||||
@@ -79373,12 +79373,12 @@
|
||||
},
|
||||
/obj/structure/window/reinforced,
|
||||
/obj/structure/rack,
|
||||
/obj/item/tank/jetpack/carbondioxide{
|
||||
/obj/item/tank/jetpack/carbondioxide/eva{
|
||||
pixel_x = 4;
|
||||
pixel_y = -1
|
||||
},
|
||||
/obj/item/tank/jetpack/carbondioxide,
|
||||
/obj/item/tank/jetpack/carbondioxide{
|
||||
/obj/item/tank/jetpack/carbondioxide/eva,
|
||||
/obj/item/tank/jetpack/carbondioxide/eva{
|
||||
pixel_x = -4;
|
||||
pixel_y = 1
|
||||
},
|
||||
@@ -80186,11 +80186,11 @@
|
||||
/area/engine/storage)
|
||||
"cEi" = (
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/item/tank/jetpack/carbondioxide{
|
||||
/obj/item/tank/jetpack/carbondioxide/eva{
|
||||
pixel_x = 3;
|
||||
pixel_y = 3
|
||||
},
|
||||
/obj/item/tank/jetpack/carbondioxide,
|
||||
/obj/item/tank/jetpack/carbondioxide/eva,
|
||||
/obj/machinery/power/apc{
|
||||
dir = 4;
|
||||
name = "Engineering Storage APC";
|
||||
|
||||
@@ -47699,12 +47699,12 @@
|
||||
},
|
||||
/obj/structure/window/reinforced,
|
||||
/obj/structure/rack,
|
||||
/obj/item/tank/jetpack/carbondioxide{
|
||||
/obj/item/tank/jetpack/carbondioxide/eva{
|
||||
pixel_x = 4;
|
||||
pixel_y = -1
|
||||
},
|
||||
/obj/item/tank/jetpack/carbondioxide,
|
||||
/obj/item/tank/jetpack/carbondioxide{
|
||||
/obj/item/tank/jetpack/carbondioxide/eva,
|
||||
/obj/item/tank/jetpack/carbondioxide/eva{
|
||||
pixel_x = -4;
|
||||
pixel_y = 1
|
||||
},
|
||||
|
||||
@@ -16464,8 +16464,8 @@
|
||||
/area/storage/eva)
|
||||
"aNt" = (
|
||||
/obj/structure/rack,
|
||||
/obj/item/tank/jetpack/carbondioxide,
|
||||
/obj/item/tank/jetpack/carbondioxide{
|
||||
/obj/item/tank/jetpack/carbondioxide/eva,
|
||||
/obj/item/tank/jetpack/carbondioxide/eva{
|
||||
pixel_x = -4;
|
||||
pixel_y = 1
|
||||
},
|
||||
@@ -35713,13 +35713,13 @@
|
||||
/obj/structure/extinguisher_cabinet{
|
||||
pixel_x = -26
|
||||
},
|
||||
/obj/machinery/rnd/production/protolathe/department/medical,
|
||||
/obj/effect/turf_decal/tile/blue{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/turf_decal/tile/blue{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/rnd/production/techfab/department/medical,
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/medical/medbay/central)
|
||||
"bEw" = (
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters)
|
||||
#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params)
|
||||
#define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target)
|
||||
#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): ()
|
||||
|
||||
// /mob/living signals
|
||||
#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
#define CAT_SANDWICH "Sandwiches"
|
||||
#define CAT_SOUP "Soups"
|
||||
#define CAT_SPAGHETTI "Spaghettis"
|
||||
#define CAT_SUSHI "Fish"
|
||||
#define CAT_FISH "Fish"
|
||||
#define CAT_ICE "Frozen"
|
||||
|
||||
#define RCD_FLOORWALL 1
|
||||
|
||||
@@ -16,3 +16,4 @@
|
||||
#define DRINK_GOOD 2
|
||||
#define DRINK_VERYGOOD 3
|
||||
#define DRINK_FANTASTIC 4
|
||||
#define FOOD_AMAZING 5
|
||||
|
||||
@@ -114,8 +114,9 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
|
||||
|
||||
#define TRANSITIONEDGE 7 //Distance from edge to move to another z-level
|
||||
|
||||
#define BE_CLOSE 1 //in the case of a silicon, to select if they need to be next to the atom
|
||||
#define NO_DEXTERY 1 //if other mobs (monkeys, aliens, etc) can use this
|
||||
#define BE_CLOSE TRUE //in the case of a silicon, to select if they need to be next to the atom
|
||||
#define NO_DEXTERY TRUE //if other mobs (monkeys, aliens, etc) can use this
|
||||
#define NO_TK TRUE
|
||||
//used by canUseTopic()
|
||||
|
||||
//singularity defines
|
||||
@@ -265,6 +266,15 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
|
||||
GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE))
|
||||
|
||||
//pda icon reskins
|
||||
#define PDA_SKIN_CLASSIC "Classic"
|
||||
#define PDA_SKIN_ALT "Holographic"
|
||||
#define PDA_SKIN_RUGGED "Rugged"
|
||||
#define PDA_SKIN_MODERN "Modern"
|
||||
|
||||
GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_SKIN_ALT = 'icons/obj/pda_alt.dmi',
|
||||
PDA_SKIN_RUGGED = 'icons/obj/pda_rugged.dmi', PDA_SKIN_MODERN = 'icons/obj/pda_modern.dmi'))
|
||||
|
||||
//Color Defines
|
||||
#define OOC_COLOR "#002eb8"
|
||||
#define AOOC_COLOR "#b8002e"
|
||||
|
||||
@@ -54,6 +54,10 @@
|
||||
#define BODYPART_ORGANIC 1
|
||||
#define BODYPART_ROBOTIC 2
|
||||
|
||||
#define BODYPART_NOT_DISABLED 0
|
||||
#define BODYPART_DISABLED_DAMAGE 1
|
||||
#define BODYPART_DISABLED_PARALYSIS 2
|
||||
|
||||
#define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/human_parts_greyscale.dmi'
|
||||
#define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augmentation/augments.dmi'
|
||||
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
#define STIMULUM_ABSOLUTE_DROP 0.00000335
|
||||
#define REACTION_OPPRESSION_THRESHOLD 5
|
||||
#define NOBLIUM_FORMATION_ENERGY 2e9 //1 Mole of Noblium takes the planck energy to condense.
|
||||
//Research point amounts
|
||||
#define NOBLIUM_RESEARCH_AMOUNT 1000
|
||||
#define BZ_RESEARCH_AMOUNT 150
|
||||
#define MIASMA_RESEARCH_AMOUNT 160
|
||||
#define STIMULUM_RESEARCH_AMOUNT 50
|
||||
//Plasma fusion properties
|
||||
#define FUSION_ENERGY_THRESHOLD 3e9 //Amount of energy it takes to start a fusion reaction
|
||||
#define FUSION_TEMPERATURE_THRESHOLD 1000 //Temperature required to start a fusion reaction
|
||||
|
||||
@@ -102,7 +102,6 @@
|
||||
#define FIRE_PRIORITY_SPACEDRIFT 30
|
||||
#define FIRE_PRIORITY_FIELDS 30
|
||||
#define FIRE_PRIOTITY_SMOOTHING 35
|
||||
#define FIRE_PRIORITY_ORBIT 35
|
||||
#define FIRE_PRIORITY_NETWORKS 40
|
||||
#define FIRE_PRIORITY_OBJ 40
|
||||
#define FIRE_PRIORITY_ACID 40
|
||||
|
||||
@@ -108,7 +108,15 @@
|
||||
#define TRAIT_NOHARDCRIT "nohardcrit"
|
||||
#define TRAIT_NOSOFTCRIT "nosoftcrit"
|
||||
#define TRAIT_MINDSHIELD "mindshield"
|
||||
#define TRAIT_PARALYSIS_L_ARM "para-l-arm" //These are used for brain-based paralysis, where replacing the limb won't fix it
|
||||
#define TRAIT_PARALYSIS_R_ARM "para-r-arm"
|
||||
#define TRAIT_PARALYSIS_L_LEG "para-l-leg"
|
||||
#define TRAIT_PARALYSIS_R_LEG "para-r-leg"
|
||||
#define TRAIT_STRONG_GRABBER "strong_grabber"
|
||||
#define TRAIT_CALCIUM_HEALER "calcium_healer"
|
||||
|
||||
//non-mob traits
|
||||
#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it
|
||||
|
||||
#define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance"
|
||||
#define TRAIT_AGEUSIA "ageusia"
|
||||
@@ -130,6 +138,7 @@
|
||||
#define TRAIT_CROCRIN_IMMUNE "crocin_immune"
|
||||
#define TRAIT_NYMPHO "nymphomania"
|
||||
#define TRAIT_MASO "masochism"
|
||||
#define TRAIT_PARA "paraplegic"
|
||||
#define TRAIT_EMPATH "empath"
|
||||
#define TRAIT_FRIENDLY "friendly"
|
||||
#define TRAIT_ASSBLASTUSA "assblastusa"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
. = new_angle - old_angle
|
||||
Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT
|
||||
|
||||
/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3)
|
||||
/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3, parallel = TRUE)
|
||||
if(!segments)
|
||||
return
|
||||
var/segment = 360/segments
|
||||
@@ -18,7 +18,11 @@
|
||||
|
||||
speed /= segments
|
||||
|
||||
animate(src, transform = matrices[1], time = speed, loops)
|
||||
if(parallel)
|
||||
animate(src, transform = matrices[1], time = speed, loops , flags = ANIMATION_PARALLEL)
|
||||
else
|
||||
animate(src, transform = matrices[1], time = speed, loops)
|
||||
|
||||
for(var/i in 2 to segments) //2 because 1 is covered above
|
||||
animate(transform = matrices[i], time = speed)
|
||||
//doesn't have an object argument because this is "Stacking" with the animate call above
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
"balls_amount" = 2,
|
||||
"balls_sack_size" = BALLS_SACK_SIZE_DEF,
|
||||
"balls_size" = BALLS_SIZE_DEF,
|
||||
"balls_shape" = "Pair",
|
||||
"balls_shape" = "Single",
|
||||
"balls_cum_rate" = CUM_RATE,
|
||||
"balls_cum_mult" = CUM_RATE_MULT,
|
||||
"balls_efficiency" = CUM_EFFICIENCY,
|
||||
|
||||
74
code/__HELPERS/reagents.dm
Normal file
74
code/__HELPERS/reagents.dm
Normal file
@@ -0,0 +1,74 @@
|
||||
/proc/chem_recipes_do_conflict(datum/chemical_reaction/r1, datum/chemical_reaction/r2)
|
||||
//do the non-list tests first, because they are cheaper
|
||||
if(r1.required_container != r2.required_container)
|
||||
return FALSE
|
||||
if(r1.is_cold_recipe == r2.is_cold_recipe)
|
||||
if(r1.required_temp != r2.required_temp)
|
||||
//one reaction requires a more extreme temperature than the other, so there is no conflict
|
||||
return FALSE
|
||||
else
|
||||
var/datum/chemical_reaction/cold_one = r1.is_cold_recipe ? r1 : r2
|
||||
var/datum/chemical_reaction/warm_one = r1.is_cold_recipe ? r2 : r1
|
||||
if(cold_one.required_temp < warm_one.required_temp)
|
||||
//the range of temperatures does not overlap, so there is no conflict
|
||||
return FALSE
|
||||
|
||||
//find the reactions with the shorter and longer required_reagents list
|
||||
var/datum/chemical_reaction/long_req
|
||||
var/datum/chemical_reaction/short_req
|
||||
if(r1.required_reagents.len > r2.required_reagents.len)
|
||||
long_req = r1
|
||||
short_req = r2
|
||||
else if(r1.required_reagents.len < r2.required_reagents.len)
|
||||
long_req = r2
|
||||
short_req = r1
|
||||
else
|
||||
//if they are the same length, sort instead by the length of the catalyst list
|
||||
//this is important if the required_reagents lists are the same
|
||||
if(r1.required_catalysts.len > r2.required_catalysts.len)
|
||||
long_req = r1
|
||||
short_req = r2
|
||||
else
|
||||
long_req = r2
|
||||
short_req = r1
|
||||
|
||||
|
||||
//check if the shorter reaction list is a subset of the longer one
|
||||
var/list/overlap = r1.required_reagents & r2.required_reagents
|
||||
if(overlap.len != short_req.required_reagents.len)
|
||||
//there is at least one reagent in the short list that is not in the long list, so there is no conflict
|
||||
return FALSE
|
||||
|
||||
//check to see if the shorter reaction's catalyst list is also a subset of the longer reaction's catalyst list
|
||||
//if the longer reaction's catalyst list is a subset of the shorter ones, that is fine
|
||||
//if the reaction lists are the same, the short reaction will have the shorter required_catalysts list, so it will register as a conflict
|
||||
var/list/short_minus_long_catalysts = short_req.required_catalysts - long_req.required_catalysts
|
||||
if(short_minus_long_catalysts.len)
|
||||
//there is at least one unique catalyst for the short reaction, so there is no conflict
|
||||
return FALSE
|
||||
|
||||
//if we got this far, the longer reaction will be impossible to create if the shorter one is earlier in GLOB.chemical_reactions_list, and will require the reagents to be added in a particular order otherwise
|
||||
return TRUE
|
||||
|
||||
/proc/get_chemical_reaction(id)
|
||||
if(!GLOB.chemical_reactions_list)
|
||||
return
|
||||
for(var/reagent in GLOB.chemical_reactions_list)
|
||||
for(var/datum/chemical_reaction/R in GLOB.chemical_reactions_list[reagent])
|
||||
if(R.id == id)
|
||||
return R
|
||||
|
||||
/proc/remove_chemical_reaction(datum/chemical_reaction/R)
|
||||
if(!GLOB.chemical_reactions_list || !R)
|
||||
return
|
||||
for(var/rid in R.required_reagents)
|
||||
GLOB.chemical_reactions_list[rid] -= R
|
||||
|
||||
//see build_chemical_reactions_list in holder.dm for explanations
|
||||
/proc/add_chemical_reaction(datum/chemical_reaction/R)
|
||||
if(!GLOB.chemical_reactions_list || !R.id || !R.required_reagents || !R.required_reagents.len)
|
||||
return
|
||||
var/primary_reagent = R.required_reagents[1]
|
||||
if(!GLOB.chemical_reactions_list[primary_reagent])
|
||||
GLOB.chemical_reactions_list[primary_reagent] = list()
|
||||
GLOB.chemical_reactions_list[primary_reagent] += R
|
||||
@@ -70,3 +70,6 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0)
|
||||
if(hour)
|
||||
hourT = " and [hour] hour[(hour != 1)? "s":""]"
|
||||
return "[day] day[(day != 1)? "s":""][hourT][minuteT][secondT]"
|
||||
|
||||
/proc/daysSince(realtimev)
|
||||
return round((world.realtime - realtimev) / (24 HOURS))
|
||||
|
||||
@@ -44,6 +44,7 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
|
||||
/obj/item/flashlight = 4,
|
||||
/obj/item/flashlight/pen = 1,
|
||||
/obj/item/flashlight/glowstick/random = 4,
|
||||
/obj/effect/spawner/lootdrop/mre = 3,
|
||||
/obj/item/multitool = 2,
|
||||
/obj/item/radio/off = 2,
|
||||
/obj/item/t_scanner = 5,
|
||||
|
||||
@@ -18,3 +18,12 @@ GLOBAL_LIST_EMPTY(powernets)
|
||||
GLOBAL_VAR_INIT(bsa_unlock, FALSE) //BSA unlocked by head ID swipes
|
||||
|
||||
GLOBAL_LIST_EMPTY(player_details) // ckey -> /datum/player_details
|
||||
|
||||
// All religion stuff
|
||||
GLOBAL_VAR(religion)
|
||||
GLOBAL_VAR(deity)
|
||||
GLOBAL_VAR(bible_name)
|
||||
GLOBAL_VAR(bible_icon_state)
|
||||
GLOBAL_VAR(bible_item_state)
|
||||
GLOBAL_VAR(holy_weapon_type)
|
||||
GLOBAL_VAR(holy_armor_type)
|
||||
@@ -23,6 +23,9 @@
|
||||
return
|
||||
next_click = world.time + 1
|
||||
|
||||
if(!can_interact_with(A))
|
||||
return
|
||||
|
||||
if(multicam_on)
|
||||
var/turf/T = get_turf(A)
|
||||
if(T)
|
||||
@@ -60,7 +63,6 @@
|
||||
controlled_mech.click_action(A, src, params) //Override AI normal click behavior.
|
||||
return
|
||||
|
||||
return
|
||||
if(modifiers["shift"])
|
||||
ShiftClickOn(A)
|
||||
return
|
||||
|
||||
@@ -50,7 +50,7 @@ SUBSYSTEM_DEF(augury)
|
||||
watchers -= w
|
||||
continue
|
||||
var/mob/dead/observer/O = w
|
||||
if(biggest_doom && (!O.orbiting || O.orbiting.orbiting != biggest_doom))
|
||||
if(biggest_doom && (!O.orbiting || O.orbiting.parent != biggest_doom))
|
||||
O.ManualFollow(biggest_doom)
|
||||
|
||||
/datum/action/innate/augury
|
||||
|
||||
@@ -256,10 +256,13 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
/datum/controller/subsystem/mapping/proc/generate_station_area_list()
|
||||
var/list/station_areas_blacklist = typecacheof(list(/area/space, /area/mine, /area/ruin, /area/asteroid/nearstation))
|
||||
for(var/area/A in world)
|
||||
var/turf/picked = safepick(get_area_turfs(A.type))
|
||||
if(picked && is_station_level(picked.z))
|
||||
if(!(A.type in GLOB.the_station_areas) && !is_type_in_typecache(A, station_areas_blacklist))
|
||||
GLOB.the_station_areas.Add(A.type)
|
||||
if (is_type_in_typecache(A, station_areas_blacklist))
|
||||
continue
|
||||
if (!A.contents.len || !A.unique)
|
||||
continue
|
||||
var/turf/picked = A.contents[1]
|
||||
if (is_station_level(picked.z))
|
||||
GLOB.the_station_areas += A.type
|
||||
|
||||
if(!GLOB.the_station_areas.len)
|
||||
log_world("ERROR: Station areas list failed to generate!")
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
SUBSYSTEM_DEF(orbit)
|
||||
name = "Orbits"
|
||||
priority = FIRE_PRIORITY_ORBIT
|
||||
wait = 2
|
||||
flags = SS_NO_INIT|SS_TICKER
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/list/processing = list()
|
||||
|
||||
/datum/controller/subsystem/orbit/stat_entry()
|
||||
..("P:[processing.len]")
|
||||
|
||||
|
||||
/datum/controller/subsystem/orbit/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = processing.Copy()
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while (currentrun.len)
|
||||
var/datum/orbit/O = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if (!O)
|
||||
processing -= O
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
if (!O.orbiter)
|
||||
qdel(O)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
if (O.lastprocess >= world.time) //we already checked recently
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
var/targetloc = get_turf(O.orbiting)
|
||||
if (targetloc != O.lastloc || O.orbiter.loc != targetloc)
|
||||
O.Check(targetloc)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
LoadPhotoPersistence()
|
||||
if(CONFIG_GET(flag/use_antag_rep))
|
||||
LoadAntagReputation()
|
||||
LoadRandomizedRecipes()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadSatchels()
|
||||
@@ -206,6 +207,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
SavePhotoPersistence() //THIS IS PERSISTENCE, NOT THE LOGGING PORTION.
|
||||
if(CONFIG_GET(flag/use_antag_rep))
|
||||
CollectAntagReputation()
|
||||
SaveRandomizedRecipes()
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/GetPhotoAlbums()
|
||||
var/album_path = file("data/photo_albums.json")
|
||||
@@ -371,3 +373,43 @@ SUBSYSTEM_DEF(persistence)
|
||||
fdel(FILE_ANTAG_REP)
|
||||
text2file(json_encode(antag_rep), FILE_ANTAG_REP)
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadRandomizedRecipes()
|
||||
var/json_file = file("data/RandomizedChemRecipes.json")
|
||||
var/json
|
||||
if(fexists(json_file))
|
||||
json = json_decode(file2text(json_file))
|
||||
|
||||
for(var/randomized_type in subtypesof(/datum/chemical_reaction/randomized))
|
||||
var/datum/chemical_reaction/randomized/R = new randomized_type
|
||||
var/loaded = FALSE
|
||||
if(R.persistent && json)
|
||||
var/list/recipe_data = json[R.id]
|
||||
if(recipe_data && R.LoadOldRecipe(recipe_data) && (daysSince(R.created) <= R.persistence_period))
|
||||
loaded = TRUE
|
||||
if(!loaded) //We do not have information for whatever reason, just generate new one
|
||||
R.GenerateRecipe()
|
||||
|
||||
if(!R.HasConflicts()) //Might want to try again if conflicts happened in the future.
|
||||
add_chemical_reaction(R)
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/SaveRandomizedRecipes()
|
||||
var/json_file = file("data/RandomizedChemRecipes.json")
|
||||
var/list/file_data = list()
|
||||
|
||||
//asert globchems done
|
||||
for(var/randomized_type in subtypesof(/datum/chemical_reaction/randomized))
|
||||
var/datum/chemical_reaction/randomized/R = randomized_type
|
||||
R = get_chemical_reaction(initial(R.id)) //ew, would be nice to add some simple tracking
|
||||
if(R && R.persistent && R.id)
|
||||
var/recipe_data = list()
|
||||
recipe_data["timestamp"] = R.created
|
||||
recipe_data["required_reagents"] = R.required_reagents
|
||||
recipe_data["required_catalysts"] = R.required_catalysts
|
||||
recipe_data["required_temp"] = R.required_temp
|
||||
recipe_data["is_cold_recipe"] = R.is_cold_recipe
|
||||
recipe_data["results"] = R.results
|
||||
recipe_data["required_container"] = "[R.required_container]"
|
||||
file_data["[R.id]"] = recipe_data
|
||||
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
SUBSYSTEM_DEF(religion)
|
||||
name = "Religion"
|
||||
flags = SS_NO_FIRE|SS_NO_INIT
|
||||
|
||||
var/religion
|
||||
var/deity
|
||||
var/bible_name
|
||||
var/bible_icon_state
|
||||
var/bible_item_state
|
||||
var/holy_weapon_type
|
||||
var/holy_armor_type
|
||||
@@ -60,18 +60,68 @@
|
||||
|
||||
/datum/brain_trauma/severe/paralysis
|
||||
name = "Paralysis"
|
||||
desc = "Patient's brain can no longer control its motor functions."
|
||||
desc = "Patient's brain can no longer control part of its motor functions."
|
||||
scan_desc = "cerebral paralysis"
|
||||
gain_text = "<span class='warning'>You can't feel your body anymore!</span>"
|
||||
lose_text = "<span class='notice'>You can feel your limbs again!</span>"
|
||||
gain_text = ""
|
||||
lose_text = ""
|
||||
var/paralysis_type
|
||||
var/list/paralysis_traits = list()
|
||||
//for descriptions
|
||||
|
||||
/datum/brain_trauma/severe/paralysis/on_life()
|
||||
owner.Knockdown(200, ignore_canknockdown = TRUE)
|
||||
/datum/brain_trauma/severe/paralysis/New(specific_type)
|
||||
if(specific_type)
|
||||
paralysis_type = specific_type
|
||||
if(!paralysis_type)
|
||||
paralysis_type = pick("full","left","right","arms","legs","r_arm","l_arm","r_leg","l_leg")
|
||||
var/subject
|
||||
switch(paralysis_type)
|
||||
if("full")
|
||||
subject = "your body"
|
||||
paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG)
|
||||
if("left")
|
||||
subject = "the left side of your body"
|
||||
paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_L_LEG)
|
||||
if("right")
|
||||
subject = "the right side of your body"
|
||||
paralysis_traits = list(TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_R_LEG)
|
||||
if("arms")
|
||||
subject = "your arms"
|
||||
paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM)
|
||||
if("legs")
|
||||
subject = "your legs"
|
||||
paralysis_traits = list(TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG)
|
||||
if("r_arm")
|
||||
subject = "your right arm"
|
||||
paralysis_traits = list(TRAIT_PARALYSIS_R_ARM)
|
||||
if("l_arm")
|
||||
subject = "your left arm"
|
||||
paralysis_traits = list(TRAIT_PARALYSIS_L_ARM)
|
||||
if("r_leg")
|
||||
subject = "your right leg"
|
||||
paralysis_traits = list(TRAIT_PARALYSIS_R_LEG)
|
||||
if("l_leg")
|
||||
subject = "your left leg"
|
||||
paralysis_traits = list(TRAIT_PARALYSIS_L_LEG)
|
||||
|
||||
gain_text = "<span class='warning'>You can't feel [subject] anymore!</span>"
|
||||
lose_text = "<span class='notice'>You can feel [subject] again!</span>"
|
||||
|
||||
/datum/brain_trauma/severe/paralysis/on_gain()
|
||||
..()
|
||||
for(var/X in paralysis_traits)
|
||||
ADD_TRAIT(owner, X, "trauma_paralysis")
|
||||
owner.update_disabled_bodyparts()
|
||||
|
||||
/datum/brain_trauma/severe/paralysis/on_lose()
|
||||
owner.SetKnockdown(0)
|
||||
..()
|
||||
for(var/X in paralysis_traits)
|
||||
REMOVE_TRAIT(owner, X, "trauma_paralysis")
|
||||
owner.update_disabled_bodyparts()
|
||||
|
||||
/datum/brain_trauma/severe/paralysis/paraplegic
|
||||
//can_gain = FALSE maybe breaks.
|
||||
paralysis_type = "legs"
|
||||
resilience = TRAUMA_RESILIENCE_ABSOLUTE
|
||||
|
||||
/datum/brain_trauma/severe/narcolepsy
|
||||
name = "Narcolepsy"
|
||||
@@ -203,4 +253,4 @@
|
||||
|
||||
/datum/brain_trauma/severe/pacifism/on_lose()
|
||||
REMOVE_TRAIT(owner, TRAIT_PACIFISM, TRAUMA_TRAIT)
|
||||
..()
|
||||
..()
|
||||
|
||||
156
code/datums/components/orbiter.dm
Normal file
156
code/datums/components/orbiter.dm
Normal file
@@ -0,0 +1,156 @@
|
||||
/datum/component/orbiter
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
||||
var/list/orbiters
|
||||
var/datum/callback/orbiter_spy
|
||||
var/datum/callback/orbited_spy
|
||||
|
||||
//radius: range to orbit at, radius of the circle formed by orbiting (in pixels)
|
||||
//clockwise: whether you orbit clockwise or anti clockwise
|
||||
//rotation_speed: how fast to rotate (how many ds should it take for a rotation to complete)
|
||||
//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default.
|
||||
//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts
|
||||
/datum/component/orbiter/Initialize(atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
|
||||
if(!istype(orbiter) || !isatom(parent) || isarea(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
orbiters = list()
|
||||
orbiter_spy = CALLBACK(src, .proc/orbiter_move_react)
|
||||
orbited_spy = CALLBACK(src, .proc/move_react)
|
||||
|
||||
var/atom/master = parent
|
||||
master.orbiters = src
|
||||
|
||||
begin_orbit(orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
|
||||
|
||||
/datum/component/orbiter/RegisterWithParent()
|
||||
var/atom/target = parent
|
||||
while(ismovableatom(target))
|
||||
RegisterSignal(target, COMSIG_MOVABLE_MOVED, orbited_spy)
|
||||
target = target.loc
|
||||
|
||||
/datum/component/orbiter/UnregisterFromParent()
|
||||
var/atom/target = parent
|
||||
while(ismovableatom(target))
|
||||
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
|
||||
target = target.loc
|
||||
|
||||
/datum/component/orbiter/Destroy()
|
||||
var/atom/master = parent
|
||||
master.orbiters = null
|
||||
for(var/i in orbiters)
|
||||
end_orbit(i)
|
||||
orbiters = null
|
||||
QDEL_NULL(orbiter_spy)
|
||||
QDEL_NULL(orbited_spy)
|
||||
return ..()
|
||||
|
||||
/datum/component/orbiter/InheritComponent(datum/component/orbiter/newcomp, original, list/arguments)
|
||||
if(arguments)
|
||||
begin_orbit(arglist(arguments))
|
||||
return
|
||||
// The following only happens on component transfers
|
||||
orbiters += newcomp.orbiters
|
||||
|
||||
/datum/component/orbiter/PostTransfer()
|
||||
if(!isatom(parent) || isarea(parent) || !get_turf(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
move_react()
|
||||
|
||||
/datum/component/orbiter/proc/begin_orbit(atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
|
||||
if(orbiter.orbiting)
|
||||
if(orbiter.orbiting == src)
|
||||
orbiter.orbiting.end_orbit(orbiter, TRUE)
|
||||
else
|
||||
orbiter.orbiting.end_orbit(orbiter)
|
||||
orbiters[orbiter] = TRUE
|
||||
orbiter.orbiting = src
|
||||
RegisterSignal(orbiter, COMSIG_MOVABLE_MOVED, orbiter_spy)
|
||||
var/matrix/initial_transform = matrix(orbiter.transform)
|
||||
|
||||
// Head first!
|
||||
if(pre_rotation)
|
||||
var/matrix/M = matrix(orbiter.transform)
|
||||
var/pre_rot = 90
|
||||
if(!clockwise)
|
||||
pre_rot = -90
|
||||
M.Turn(pre_rot)
|
||||
orbiter.transform = M
|
||||
|
||||
var/matrix/shift = matrix(orbiter.transform)
|
||||
shift.Translate(0, radius)
|
||||
orbiter.transform = shift
|
||||
|
||||
orbiter.SpinAnimation(rotation_speed, -1, clockwise, rotation_segments, parallel = FALSE)
|
||||
|
||||
//we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit
|
||||
orbiter.transform = initial_transform
|
||||
orbiter.forceMove(get_turf(parent))
|
||||
to_chat(orbiter, "<span class='notice'>Now orbiting [parent].</span>")
|
||||
|
||||
/datum/component/orbiter/proc/end_orbit(atom/movable/orbiter, refreshing=FALSE)
|
||||
if(!orbiters[orbiter])
|
||||
return
|
||||
UnregisterSignal(orbiter, COMSIG_MOVABLE_MOVED)
|
||||
orbiter.SpinAnimation(0, 0)
|
||||
orbiters -= orbiter
|
||||
orbiter.stop_orbit(src)
|
||||
orbiter.orbiting = null
|
||||
if(!refreshing && !length(orbiters) && !QDELING(src))
|
||||
qdel(src)
|
||||
|
||||
// This proc can receive signals by either the thing being directly orbited or anything holding it
|
||||
/datum/component/orbiter/proc/move_react(atom/orbited, atom/oldloc, direction)
|
||||
set waitfor = FALSE // Transfer calls this directly and it doesnt care if the ghosts arent done moving
|
||||
|
||||
var/atom/movable/master = parent
|
||||
if(master.loc == oldloc)
|
||||
return
|
||||
|
||||
var/turf/newturf = get_turf(master)
|
||||
if(!newturf)
|
||||
qdel(src)
|
||||
|
||||
// Handling the signals of stuff holding us (or not anymore)
|
||||
// These are prety rarely activated, how often are you following something in a bag?
|
||||
if(oldloc && !isturf(oldloc)) // We used to be registered to it, probably
|
||||
var/atom/target = oldloc
|
||||
while(ismovableatom(target))
|
||||
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
|
||||
target = target.loc
|
||||
if(orbited?.loc && orbited.loc != newturf) // We want to know when anything holding us moves too
|
||||
var/atom/target = orbited.loc
|
||||
while(ismovableatom(target))
|
||||
RegisterSignal(target, COMSIG_MOVABLE_MOVED, orbited_spy, TRUE)
|
||||
target = target.loc
|
||||
|
||||
var/atom/curloc = master.loc
|
||||
for(var/i in orbiters)
|
||||
var/atom/movable/thing = i
|
||||
if(QDELETED(thing) || thing.loc == newturf)
|
||||
continue
|
||||
thing.forceMove(newturf)
|
||||
if(CHECK_TICK && master.loc != curloc)
|
||||
// We moved again during the checktick, cancel current operation
|
||||
break
|
||||
|
||||
|
||||
/datum/component/orbiter/proc/orbiter_move_react(atom/movable/orbiter, atom/oldloc, direction)
|
||||
if(orbiter.loc == get_turf(parent))
|
||||
return
|
||||
end_orbit(orbiter)
|
||||
|
||||
/////////////////////
|
||||
|
||||
/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE)
|
||||
if(!istype(A) || !get_turf(A) || A == src)
|
||||
return
|
||||
|
||||
return A.AddComponent(/datum/component/orbiter, src, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
|
||||
|
||||
/atom/movable/proc/stop_orbit(datum/component/orbiter/orbits)
|
||||
return // We're just a simple hook
|
||||
|
||||
/atom/proc/transfer_observers_to(atom/target)
|
||||
if(!orbiters || !istype(target) || !get_turf(target) || target == src)
|
||||
return
|
||||
target.TakeComponent(orbiters)
|
||||
@@ -20,3 +20,4 @@
|
||||
/datum/component/storage/concrete/emergency/proc/unlock_me(datum/source)
|
||||
if(locked)
|
||||
set_locked(source, FALSE)
|
||||
return TRUE
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
var/current_target
|
||||
var/datum/martial_art/base // The permanent style. This will be null unless the martial art is temporary
|
||||
var/deflection_chance = 0 //Chance to deflect projectiles
|
||||
var/reroute_deflection = FALSE //Delete the bullet, or actually deflect it in some direction?
|
||||
var/block_chance = 0 //Chance to block melee attacks using items while on throw mode.
|
||||
var/restraining = 0 //used in cqc's disarm_act to check if the disarmed is being restrained and so whether they should be put in a chokehold or not
|
||||
var/help_verb
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
/datum/martial_art/the_sleeping_carp
|
||||
name = "The Sleeping Carp"
|
||||
deflection_chance = 100
|
||||
reroute_deflection = TRUE
|
||||
no_guns = TRUE
|
||||
allow_temp_override = FALSE
|
||||
help_verb = /mob/living/carbon/human/proc/sleeping_carp_help
|
||||
|
||||
@@ -22,3 +22,8 @@
|
||||
description = "<span class='nicegreen'>That drink was amazing!</span>\n"
|
||||
mood_change = 4
|
||||
timeout = 1200
|
||||
|
||||
/datum/mood_event/amazingtaste
|
||||
description = "<span class='nicegreen'>Amazing taste!</span>\n"
|
||||
mood_change = 50
|
||||
timeout = 10 MINUTES
|
||||
|
||||
@@ -117,6 +117,16 @@
|
||||
description = "<span class='warning'>I'm missing my family heirloom...</span>\n"
|
||||
mood_change = -4
|
||||
|
||||
/datum/mood_event/loud_gong
|
||||
description = "<span class='warning'>That loud gong noise really hurt my ears!</span>\n"
|
||||
mood_change = -3
|
||||
timeout = 1200
|
||||
|
||||
/datum/mood_event/spooked
|
||||
description = "<span class='warning'>The rattling of those bones...It still haunts me.</span>\n"
|
||||
mood_change = -4
|
||||
timeout = 2400
|
||||
|
||||
//These are unused so far but I want to remember them to use them later
|
||||
/datum/mood_event/cloned_corpse
|
||||
description = "<span class='boldwarning'>I recently saw my own corpse...</span>\n"
|
||||
|
||||
@@ -299,3 +299,9 @@
|
||||
suffix = "arcade.dmm"
|
||||
name = "Space Arcade"
|
||||
description = "A lonely arcade in the depths of space."
|
||||
|
||||
/datum/map_template/ruin/space/hermit
|
||||
id = "spacehermit"
|
||||
suffix = "spacehermit.dmm"
|
||||
name = "Space Hermit"
|
||||
description = "A late awakening cryo pod in a crashed escape pod wakes up to find what befell of his fellow survivors. Contains all the necessary resources to actually make it out alive. Good luck."
|
||||
|
||||
@@ -38,13 +38,13 @@
|
||||
var/obj/item/heirloom_type
|
||||
switch(quirk_holder.mind.assigned_role)
|
||||
if("Clown")
|
||||
heirloom_type = /obj/item/paint/anycolor
|
||||
heirloom_type = /obj/item/bikehorn/golden
|
||||
heirloom_type = pick(/obj/item/paint/anycolor, /obj/item/bikehorn/golden)
|
||||
if("Mime")
|
||||
heirloom_type = /obj/item/paint/anycolor
|
||||
heirloom_type = /obj/item/toy/dummy
|
||||
heirloom_type = pick(/obj/item/paint/anycolor, /obj/item/toy/dummy)
|
||||
if("Cook")
|
||||
heirloom_type = /obj/item/kitchen/knife/scimitar
|
||||
if("Botanist")
|
||||
heirloom_type = pick(/obj/item/cultivator, /obj/item/reagent_containers/glass/bucket, /obj/item/storage/bag/plants, /obj/item/toy/plush/beeplushie)
|
||||
if("Medical Doctor")
|
||||
heirloom_type = /obj/item/healthanalyzer/advanced
|
||||
if("Station Engineer")
|
||||
@@ -187,6 +187,41 @@
|
||||
to_chat(quirk_holder, "<span class='boldannounce'>Your antagonistic nature has caused you to renounce your pacifism.</span>")
|
||||
qdel(src)
|
||||
|
||||
/datum/quirk/paraplegic
|
||||
name = "Paraplegic"
|
||||
desc = "Your legs do not function. Nothing will ever fix this. But hey, free wheelchair!"
|
||||
value = -3
|
||||
mob_trait = TRAIT_PARA
|
||||
human_only = TRUE
|
||||
gain_text = null // Handled by trauma.
|
||||
lose_text = null
|
||||
medical_record_text = "Patient has an untreatable impairment in motor function in the lower extremities."
|
||||
|
||||
/datum/quirk/paraplegic/add()
|
||||
var/datum/brain_trauma/severe/paralysis/paraplegic/T = new()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
H.gain_trauma(T, TRAUMA_RESILIENCE_ABSOLUTE)
|
||||
|
||||
/datum/quirk/paraplegic/on_spawn()
|
||||
if(quirk_holder.buckled) // Handle late joins being buckled to arrival shuttle chairs.
|
||||
quirk_holder.buckled.unbuckle_mob(quirk_holder)
|
||||
|
||||
var/turf/T = get_turf(quirk_holder)
|
||||
var/obj/structure/chair/spawn_chair = locate() in T
|
||||
|
||||
var/obj/vehicle/ridden/wheelchair/wheels = new(T)
|
||||
if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking
|
||||
wheels.setDir(spawn_chair.dir)
|
||||
|
||||
wheels.buckle_mob(quirk_holder)
|
||||
|
||||
// During the spawning process, they may have dropped what they were holding, due to the paralysis
|
||||
// So put the things back in their hands.
|
||||
|
||||
for(var/obj/item/I in T)
|
||||
if(I.fingerprintslast == quirk_holder.ckey)
|
||||
quirk_holder.put_in_hands(I)
|
||||
|
||||
/datum/quirk/poor_aim
|
||||
name = "Poor Aim"
|
||||
desc = "You're terrible with guns and can't line up a straight shot to save your life. Dual-wielding is right out."
|
||||
@@ -208,8 +243,12 @@
|
||||
var/slot_string = "limb"
|
||||
|
||||
/datum/quirk/prosthetic_limb/on_spawn()
|
||||
var/limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/limb_slot
|
||||
if(HAS_TRAIT(H, TRAIT_PARA))//Prevent paraplegic legs being replaced
|
||||
limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)
|
||||
else
|
||||
limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
|
||||
var/obj/item/bodypart/old_part = H.get_bodypart(limb_slot)
|
||||
var/obj/item/bodypart/prosthetic
|
||||
switch(limb_slot)
|
||||
|
||||
27
code/datums/wires/microwave.dm
Normal file
27
code/datums/wires/microwave.dm
Normal file
@@ -0,0 +1,27 @@
|
||||
/datum/wires/microwave
|
||||
holder_type = /obj/machinery/microwave
|
||||
proper_name = "Microwave"
|
||||
|
||||
/datum/wires/microwave/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_ACTIVATE
|
||||
)
|
||||
..()
|
||||
|
||||
/datum/wires/microwave/interactable(mob/user)
|
||||
. = FALSE
|
||||
var/obj/machinery/microwave/M = holder
|
||||
if(M.panel_open)
|
||||
. = TRUE
|
||||
|
||||
/datum/wires/microwave/on_pulse(wire)
|
||||
var/obj/machinery/microwave/M = holder
|
||||
switch(wire)
|
||||
if(WIRE_ACTIVATE)
|
||||
M.cook()
|
||||
|
||||
/datum/wires/microwave/on_cut(wire, mend)
|
||||
var/obj/machinery/microwave/M = holder
|
||||
switch(wire)
|
||||
if(WIRE_ACTIVATE)
|
||||
M.wire_disabled = !mend
|
||||
@@ -76,7 +76,9 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
continue
|
||||
if(GLOB.teleportlocs[AR.name])
|
||||
continue
|
||||
var/turf/picked = safepick(get_area_turfs(AR.type))
|
||||
if (!AR.contents.len)
|
||||
continue
|
||||
var/turf/picked = AR.contents[1]
|
||||
if (picked && is_station_level(picked.z))
|
||||
GLOB.teleportlocs[AR.name] = AR
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
var/list/filter_data //For handling persistent filters
|
||||
|
||||
var/datum/component/orbiter/orbiters
|
||||
|
||||
var/rad_flags = NONE // Will move to flags_1 when i can be arsed to
|
||||
var/rad_insulation = RAD_NO_INSULATION
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
var/atom/movable/pulling
|
||||
var/grab_state = 0
|
||||
var/throwforce = 0
|
||||
var/datum/component/orbiter/orbiting
|
||||
var/can_be_z_moved = TRUE
|
||||
|
||||
/atom/movable/vv_edit_var(var_name, var_value)
|
||||
@@ -296,14 +297,7 @@
|
||||
if (length(client_mobs_in_contents))
|
||||
update_parallax_contents()
|
||||
|
||||
if (orbiters)
|
||||
for (var/thing in orbiters)
|
||||
var/datum/orbit/O = thing
|
||||
O.Check()
|
||||
if (orbiting)
|
||||
orbiting.Check()
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/atom/movable/Destroy(force)
|
||||
QDEL_NULL(proximity_monitor)
|
||||
@@ -325,6 +319,10 @@
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
|
||||
if(orbiting)
|
||||
orbiting.end_orbit(src)
|
||||
orbiting = null
|
||||
|
||||
// Make sure you know what you're doing if you call this, this is intended to only be called by byond directly.
|
||||
// You probably want CanPass()
|
||||
/atom/movable/Cross(atom/movable/AM)
|
||||
|
||||
@@ -35,15 +35,14 @@
|
||||
/obj/item/pda/clear,
|
||||
/obj/item/pda/syndicate,
|
||||
/obj/item/pda/chameleon,
|
||||
/obj/item/pda/chameleon/broken)
|
||||
/obj/item/pda/chameleon/broken,
|
||||
/obj/item/pda/lieutenant)
|
||||
|
||||
for(var/P in typesof(/obj/item/pda) - blocked)
|
||||
var/obj/item/pda/D = new P
|
||||
|
||||
//D.name = "PDA Style [colorlist.len+1]" //Gotta set the name, otherwise it all comes up as "PDA"
|
||||
D.name = D.icon_state //PDAs don't have unique names, but using the sprite names works.
|
||||
|
||||
src.colorlist += D
|
||||
for(var/A in typesof(/obj/item/pda) - blocked)
|
||||
var/obj/item/pda/P = A
|
||||
var/PDA_name = initial(P.name)
|
||||
colorlist += PDA_name
|
||||
colorlist[PDA_name] = list(initial(P.icon_state), initial(P.desc), initial(P.overlays_offsets), initial(P.overlays_icons))
|
||||
|
||||
/obj/machinery/pdapainter/Destroy()
|
||||
QDEL_NULL(storedpda)
|
||||
@@ -108,22 +107,20 @@
|
||||
if(.)
|
||||
return
|
||||
|
||||
if(storedpda)
|
||||
var/obj/item/pda/P
|
||||
P = input(user, "Select your color!", "PDA Painting") as null|anything in colorlist
|
||||
if(!P)
|
||||
return
|
||||
if(!in_range(src, user))
|
||||
return
|
||||
if(!storedpda)//is the pda still there?
|
||||
return
|
||||
storedpda.icon_state = P.icon_state
|
||||
storedpda.desc = P.desc
|
||||
ejectpda()
|
||||
|
||||
else
|
||||
if(!storedpda)
|
||||
to_chat(user, "<span class='notice'>[src] is empty.</span>")
|
||||
|
||||
return
|
||||
var/choice = input(user, "Select the new skin!", "PDA Painting") as null|anything in colorlist
|
||||
if(!choice || !storedpda || !in_range(src, user))
|
||||
return
|
||||
var/list/P = colorlist[choice]
|
||||
storedpda.icon_state = P[1]
|
||||
storedpda.desc = P[2]
|
||||
storedpda.overlays_offsets = P[3]
|
||||
storedpda.overlays_icons = P[4]
|
||||
storedpda.set_new_overlays()
|
||||
storedpda.update_icon()
|
||||
ejectpda()
|
||||
|
||||
/obj/machinery/pdapainter/verb/ejectpda()
|
||||
set name = "Eject PDA"
|
||||
|
||||
@@ -168,9 +168,11 @@ Class Procs:
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/proc/dropContents()
|
||||
/obj/machinery/proc/dropContents(list/subset = null)
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/atom/movable/A in contents)
|
||||
if(subset && !(A in subset))
|
||||
continue
|
||||
A.forceMove(T)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
207
code/game/machinery/computer/arcade/battle.dm
Normal file
207
code/game/machinery/computer/arcade/battle.dm
Normal file
@@ -0,0 +1,207 @@
|
||||
// ** BATTLE ** //
|
||||
|
||||
|
||||
/obj/machinery/computer/arcade/battle
|
||||
name = "arcade machine"
|
||||
desc = "Does not support Pinball."
|
||||
icon_state = "arcade"
|
||||
circuit = /obj/item/circuitboard/computer/arcade/battle
|
||||
var/enemy_name = "Space Villain"
|
||||
var/temp = "Winners don't use space drugs" //Temporary message, for attack messages, etc
|
||||
var/player_hp = 30 //Player health/attack points
|
||||
var/player_mp = 10
|
||||
var/enemy_hp = 45 //Enemy health/attack points
|
||||
var/enemy_mp = 20
|
||||
var/gameover = FALSE
|
||||
var/blocked = FALSE //Player cannot attack/heal while set
|
||||
var/turtle = 0
|
||||
|
||||
var/turn_speed = 5 //Measured in deciseconds.
|
||||
|
||||
/obj/machinery/computer/arcade/battle/Reset()
|
||||
var/name_action
|
||||
var/name_part1
|
||||
var/name_part2
|
||||
|
||||
name_action = pick("Defeat ", "Annihilate ", "Save ", "Strike ", "Stop ", "Destroy ", "Robust ", "Romance ", "Pwn ", "Own ", "Ban ")
|
||||
|
||||
name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ")
|
||||
name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn", "Bloopers")
|
||||
|
||||
enemy_name = replacetext((name_part1 + name_part2), "the ", "")
|
||||
name = (name_action + name_part1 + name_part2)
|
||||
|
||||
/obj/machinery/computer/arcade/battle/ui_interact(mob/user)
|
||||
. = ..()
|
||||
var/dat = "<a href='byond://?src=[REF(src)];close=1'>Close</a>"
|
||||
dat += "<center><h4>[enemy_name]</h4></center>"
|
||||
|
||||
dat += "<br><center><h3>[temp]</h3></center>"
|
||||
dat += "<br><center>Health: [player_hp] | Magic: [player_mp] | Enemy Health: [enemy_hp]</center>"
|
||||
|
||||
if (gameover)
|
||||
dat += "<center><b><a href='byond://?src=[REF(src)];newgame=1'>New Game</a>"
|
||||
else
|
||||
dat += "<center><b><a href='byond://?src=[REF(src)];attack=1'>Attack</a> | "
|
||||
dat += "<a href='byond://?src=[REF(src)];heal=1'>Heal</a> | "
|
||||
dat += "<a href='byond://?src=[REF(src)];charge=1'>Recharge Power</a>"
|
||||
|
||||
dat += "</b></center>"
|
||||
var/datum/browser/popup = new(user, "arcade", "Space Villain 2000")
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/computer/arcade/battle/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if (!blocked && !gameover)
|
||||
if (href_list["attack"])
|
||||
blocked = TRUE
|
||||
var/attackamt = rand(2,6)
|
||||
temp = "You attack for [attackamt] damage!"
|
||||
playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
updateUsrDialog()
|
||||
if(turtle > 0)
|
||||
turtle--
|
||||
|
||||
sleep(turn_speed)
|
||||
enemy_hp -= attackamt
|
||||
arcade_action(usr)
|
||||
|
||||
else if (href_list["heal"])
|
||||
blocked = TRUE
|
||||
var/pointamt = rand(1,3)
|
||||
var/healamt = rand(6,8)
|
||||
temp = "You use [pointamt] magic to heal for [healamt] damage!"
|
||||
playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
updateUsrDialog()
|
||||
turtle++
|
||||
|
||||
sleep(turn_speed)
|
||||
player_mp -= pointamt
|
||||
player_hp += healamt
|
||||
blocked = TRUE
|
||||
updateUsrDialog()
|
||||
arcade_action(usr)
|
||||
|
||||
else if (href_list["charge"])
|
||||
blocked = TRUE
|
||||
var/chargeamt = rand(4,7)
|
||||
temp = "You regain [chargeamt] points"
|
||||
playsound(loc, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
player_mp += chargeamt
|
||||
if(turtle > 0)
|
||||
turtle--
|
||||
|
||||
updateUsrDialog()
|
||||
sleep(turn_speed)
|
||||
arcade_action(usr)
|
||||
|
||||
if (href_list["close"])
|
||||
usr.unset_machine()
|
||||
usr << browse(null, "window=arcade")
|
||||
|
||||
else if (href_list["newgame"]) //Reset everything
|
||||
temp = "New Round"
|
||||
player_hp = initial(player_hp)
|
||||
player_mp = initial(player_mp)
|
||||
enemy_hp = initial(enemy_hp)
|
||||
enemy_mp = initial(enemy_mp)
|
||||
gameover = FALSE
|
||||
turtle = 0
|
||||
|
||||
if(obj_flags & EMAGGED)
|
||||
Reset()
|
||||
obj_flags &= ~EMAGGED
|
||||
|
||||
add_fingerprint(usr)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/arcade/battle/proc/arcade_action(mob/user)
|
||||
if ((enemy_mp <= 0) || (enemy_hp <= 0))
|
||||
if(!gameover)
|
||||
gameover = TRUE
|
||||
temp = "[enemy_name] has fallen! Rejoice!"
|
||||
playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
|
||||
if(obj_flags & EMAGGED)
|
||||
new /obj/effect/spawner/newbomb/timer/syndicate(loc)
|
||||
new /obj/item/clothing/head/collectable/petehat(loc)
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] has outbombed Cuban Pete and been awarded a bomb.")
|
||||
log_game("[key_name(usr)] has outbombed Cuban Pete and been awarded a bomb.")
|
||||
Reset()
|
||||
obj_flags &= ~EMAGGED
|
||||
else
|
||||
prizevend(user)
|
||||
SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("win", (obj_flags & EMAGGED ? "emagged":"normal")))
|
||||
|
||||
|
||||
else if ((obj_flags & EMAGGED) && (turtle >= 4))
|
||||
var/boomamt = rand(5,10)
|
||||
temp = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!"
|
||||
playsound(loc, 'sound/arcade/boom.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
player_hp -= boomamt
|
||||
|
||||
else if ((enemy_mp <= 5) && (prob(70)))
|
||||
var/stealamt = rand(2,3)
|
||||
temp = "[enemy_name] steals [stealamt] of your power!"
|
||||
playsound(loc, 'sound/arcade/steal.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
player_mp -= stealamt
|
||||
updateUsrDialog()
|
||||
|
||||
if (player_mp <= 0)
|
||||
gameover = TRUE
|
||||
sleep(turn_speed)
|
||||
temp = "You have been drained! GAME OVER"
|
||||
playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
if(obj_flags & EMAGGED)
|
||||
usr.gib()
|
||||
SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "mana", (obj_flags & EMAGGED ? "emagged":"normal")))
|
||||
|
||||
else if ((enemy_hp <= 10) && (enemy_mp > 4))
|
||||
temp = "[enemy_name] heals for 4 health!"
|
||||
playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
enemy_hp += 4
|
||||
enemy_mp -= 4
|
||||
|
||||
else
|
||||
var/attackamt = rand(3,6)
|
||||
temp = "[enemy_name] attacks for [attackamt] damage!"
|
||||
playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
player_hp -= attackamt
|
||||
|
||||
if ((player_mp <= 0) || (player_hp <= 0))
|
||||
gameover = TRUE
|
||||
temp = "You have been crushed! GAME OVER"
|
||||
playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
if(obj_flags & EMAGGED)
|
||||
usr.gib()
|
||||
SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "hp", (obj_flags & EMAGGED ? "emagged":"normal")))
|
||||
|
||||
blocked = FALSE
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/computer/arcade/battle/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
to_chat(user, "<span class='warning'>A mesmerizing Rhumba beat starts playing from the arcade machine's speakers!</span>")
|
||||
temp = "If you die in the game, you die for real!"
|
||||
player_hp = 30
|
||||
player_mp = 10
|
||||
enemy_hp = 45
|
||||
enemy_mp = 20
|
||||
gameover = FALSE
|
||||
blocked = FALSE
|
||||
|
||||
obj_flags |= EMAGGED
|
||||
|
||||
enemy_name = "Cuban Pete"
|
||||
name = "Outbomb Cuban Pete"
|
||||
|
||||
updateUsrDialog()
|
||||
return TRUE
|
||||
392
code/game/machinery/computer/arcade/minesweeper.dm
Normal file
392
code/game/machinery/computer/arcade/minesweeper.dm
Normal file
@@ -0,0 +1,392 @@
|
||||
#define MINESWEEPER_GAME_MAIN_MENU 0
|
||||
#define MINESWEEPER_GAME_PLAYING 1
|
||||
#define MINESWEEPER_GAME_LOST 2
|
||||
#define MINESWEEPER_GAME_WON 3
|
||||
#define MINESWEEPERIMG(what) {"<img style='border:0' <span class="minesweeper16x16 [#what]"></span>"} //Basically bypassing asset.icon_tag()
|
||||
|
||||
/obj/machinery/computer/arcade/minesweeper
|
||||
name = "Minesweeper"
|
||||
desc = "An arcade machine that generates grids. It seems that the machine sparks and screeches when a grid is generated, as if it cannot cope with the intensity of generating the grid."
|
||||
icon_state = "arcade"
|
||||
circuit = /obj/item/circuitboard/computer/arcade/minesweeper
|
||||
var/area
|
||||
var/difficulty = "" //To show what difficulty you are playing
|
||||
var/flag_text = ""
|
||||
var/flagging = FALSE
|
||||
var/game_status = MINESWEEPER_GAME_MAIN_MENU
|
||||
var/mine_limit = 0
|
||||
var/mine_placed = 0
|
||||
var/mine_sound = TRUE //So it doesn't get repeated when multiple mines are exposed
|
||||
var/randomcolour = 1
|
||||
var/randomnumber = 1 //Random emagged game iteration number to be displayed, put here so it is persistent across one individual arcade machine
|
||||
var/safe_squares_revealed
|
||||
var/saved_web = "" //To display the web if you click on the arcade
|
||||
var/win_condition
|
||||
var/rows = 1
|
||||
var/columns = 1
|
||||
var/table[31][51] //Make the board boys, 30x50 board
|
||||
var/spark_spam = FALSE
|
||||
|
||||
/obj/machinery/computer/arcade/minesweeper/interact(mob/user)
|
||||
var/emagged = CHECK_BITFIELD(obj_flags, EMAGGED)
|
||||
var/dat
|
||||
if(game_status == MINESWEEPER_GAME_MAIN_MENU)
|
||||
dat += "<head><title>Minesweeper</title></head><div align='center'><b>Minesweeper[emagged ? " <font color='red'>EXTREME EDITION</font>: Iteration <font color='[randomcolour]'>#[randomnumber]</font>" : ""]</b><br>" //Different colour mix for every random number made
|
||||
dat += "<font size='2'> [emagged ? "Explode in the game, explode in real life" : "Reveal all the squares without hitting a mine"]!<br>What difficulty do you want to play?<br><br><br><br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font>"
|
||||
else
|
||||
dat = saved_web
|
||||
user = usr
|
||||
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/minesweeper)
|
||||
assets.send(user)
|
||||
|
||||
user << browse(dat,"window=minesweeper,size=400x500")
|
||||
add_fingerprint(user)
|
||||
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/computer/arcade/minesweeper/proc/reset_spark_spam()
|
||||
spark_spam = FALSE
|
||||
|
||||
/obj/machinery/computer/arcade/minesweeper/Topic(href, href_list)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/exploding_hell = FALSE //For emagged failures
|
||||
var/reset_board = FALSE
|
||||
var/mob/living/user = usr //To identify who the hell is using this window, this should also make things like aliens and monkeys able to use the machine!!
|
||||
var/web_difficulty_menu = "<font size='2'> Reveal all the squares without hitting a mine!<br>What difficulty do you want to play?<br><br><br><br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font>"
|
||||
var/web = "<head><title>Minesweeper</title></head><div align='center'><b>Minesweeper</b><br>"
|
||||
var/static_web = "<head><title>Minesweeper</title></head><div align='center'><b>Minesweeper</b><br>" //When we need to revert to the main menu we set web as this
|
||||
web = static_web
|
||||
|
||||
if(CHECK_BITFIELD(obj_flags, EMAGGED))
|
||||
web = "<head><title>Minesweeper</title></head><body><div align='center'><b>Minesweeper <font color='red'>EXTREME EDITION</font>: Iteration <font color='[randomcolour]'>#[randomnumber]</font></b><br>" //Different colour mix for every random number made
|
||||
if(!spark_spam)
|
||||
do_sparks(5, 1, src)
|
||||
spark_spam = TRUE
|
||||
addtimer(CALLBACK(src, .proc/reset_spark_spam), 30)
|
||||
|
||||
|
||||
var/startup_sound = CHECK_BITFIELD(obj_flags, EMAGGED) ? 'sound/arcade/minesweeper_emag2.ogg' : 'sound/arcade/minesweeper_startup.ogg'
|
||||
|
||||
if(href_list["Main_Menu"])
|
||||
game_status = MINESWEEPER_GAME_MAIN_MENU
|
||||
mine_limit = 0
|
||||
rows = 0
|
||||
columns = 0
|
||||
mine_placed = 0
|
||||
if(href_list["Easy"])
|
||||
playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10)
|
||||
flag_text = "OFF"
|
||||
game_status = MINESWEEPER_GAME_PLAYING
|
||||
reset_board = TRUE
|
||||
difficulty = "Easy"
|
||||
rows = 10 //9x9 board
|
||||
columns = 10
|
||||
mine_limit = 10
|
||||
if(href_list["Intermediate"])
|
||||
playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10)
|
||||
flag_text = "OFF"
|
||||
game_status = MINESWEEPER_GAME_PLAYING
|
||||
reset_board = TRUE
|
||||
difficulty = "Intermediate"
|
||||
rows = 17 //16x16 board
|
||||
columns = 17
|
||||
mine_limit = 40
|
||||
if(href_list["Hard"])
|
||||
playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10)
|
||||
flag_text = "OFF"
|
||||
game_status = MINESWEEPER_GAME_PLAYING
|
||||
reset_board = TRUE
|
||||
difficulty = "Hard"
|
||||
rows = 17 //16x30 board
|
||||
columns = 31
|
||||
mine_limit = 99
|
||||
if(href_list["Custom"])
|
||||
if(custom_generation(usr))
|
||||
flag_text = "OFF"
|
||||
game_status = MINESWEEPER_GAME_PLAYING
|
||||
reset_board = TRUE
|
||||
difficulty = "Custom"
|
||||
playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10)
|
||||
if(href_list["Flag"])
|
||||
playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
if(!flagging)
|
||||
flagging = TRUE
|
||||
flag_text = "ON"
|
||||
else
|
||||
flagging = FALSE
|
||||
flag_text = "OFF"
|
||||
|
||||
if(game_status == MINESWEEPER_GAME_MAIN_MENU)
|
||||
if(CHECK_BITFIELD(obj_flags, EMAGGED))
|
||||
playsound(loc, 'sound/arcade/minesweeper_emag2.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
web += "<font size='2'>Explode in the game, explode in real life!<br>What difficulty do you want to play?<br><br><br><br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font>"
|
||||
else
|
||||
playsound(loc, 'sound/arcade/minesweeper_startup.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
web += web_difficulty_menu
|
||||
|
||||
if(game_status == MINESWEEPER_GAME_PLAYING)
|
||||
mine_sound = TRUE
|
||||
|
||||
area = (rows-1)*(columns-1)
|
||||
|
||||
if(reset_board)
|
||||
mine_placed = 0
|
||||
var/reset_everything = TRUE
|
||||
make_mines(reset_everything)
|
||||
|
||||
safe_squares_revealed = 0
|
||||
win_condition = area-mine_placed
|
||||
|
||||
if(game_status != MINESWEEPER_GAME_MAIN_MENU)
|
||||
for(var/y1=1;y1<rows;y1++)
|
||||
for(var/x1=1;x1<columns;x1++)
|
||||
var/coordinates
|
||||
coordinates = (y1*100)+x1
|
||||
if(href_list["[coordinates]"])
|
||||
if(game_status == MINESWEEPER_GAME_PLAYING) //Don't do anything if we won or something
|
||||
if(!flagging)
|
||||
if(table[y1][x1] < 10 && table[y1][x1] >= 0) //Check that it's not already revealed, and stop flag removal if we're out of flag mode
|
||||
table[y1][x1] += 10
|
||||
if(table[y1][x1] != 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
else
|
||||
if(game_status != MINESWEEPER_GAME_LOST && game_status != MINESWEEPER_GAME_WON)
|
||||
game_status = MINESWEEPER_GAME_LOST
|
||||
if(CHECK_BITFIELD(obj_flags, EMAGGED) && !exploding_hell)
|
||||
exploding_hell = TRUE
|
||||
explode_EVERYTHING()
|
||||
if(mine_sound)
|
||||
switch(rand(1,3)) //Play every time a mine is hit
|
||||
if(1)
|
||||
playsound(loc, 'sound/arcade/minesweeper_explosion1.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
if(2)
|
||||
playsound(loc, 'sound/arcade/minesweeper_explosion2.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
if(3)
|
||||
playsound(loc, 'sound/arcade/minesweeper_explosion3.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
mine_sound = FALSE
|
||||
else
|
||||
playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
if(table[y1][x1] >= 0) //Check that it's not already flagged
|
||||
table[y1][x1] -= 10
|
||||
else if(table[y1][x1] < 0) //If flagged, remove the flag
|
||||
table[y1][x1] += 10
|
||||
if(href_list["same_board"]) //Reset the board... kinda
|
||||
if(game_status != MINESWEEPER_GAME_PLAYING)
|
||||
game_status = MINESWEEPER_GAME_PLAYING
|
||||
if(table[y1][x1] >= 10) //If revealed, become unrevealed!
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
table[y1][x1] -= 10
|
||||
if(table[y1][x1] > 10 && !reset_board)
|
||||
safe_squares_revealed += 1
|
||||
var/y2 = y1
|
||||
var/x2 = x1
|
||||
work_squares(y2, x2) //Work squares while in this loop so there's less load
|
||||
reset_board = FALSE
|
||||
|
||||
web += "<table>" //Start setting up the html table
|
||||
web += "<tbody>"
|
||||
for(var/y1=1;y1<rows;y1++)
|
||||
web += "<tr>"
|
||||
for(var/x1=1;x1<columns;x1++)
|
||||
var/coordinates
|
||||
coordinates = (y1*100)+x1
|
||||
switch(table[y1][x1])
|
||||
if(-10 to -1)
|
||||
if(game_status != MINESWEEPER_GAME_PLAYING)
|
||||
web += "<td>[MINESWEEPERIMG(flag)]</td>"
|
||||
else
|
||||
web += "<td><a href='byond://?src=[REF(src)];[coordinates]=1'>[MINESWEEPERIMG(flag)]</a></td>"
|
||||
if(0)
|
||||
if(game_status != MINESWEEPER_GAME_PLAYING)
|
||||
web += "<td>[MINESWEEPERIMG(mine)]</td>"
|
||||
else
|
||||
web += "<td><a href='byond://?src=[REF(src)];[coordinates]=1'>[MINESWEEPERIMG(hidden)]</a></td>" //Make unique hrefs for every square
|
||||
if(1 to 9)
|
||||
if(game_status != MINESWEEPER_GAME_PLAYING)
|
||||
web += "<td>[MINESWEEPERIMG(hidden)]</td>"
|
||||
else
|
||||
web += "<td><a href='byond://?src=[REF(src)];[coordinates]=1'>[MINESWEEPERIMG(hidden)]</a></td>" //Make unique hrefs for every square
|
||||
if(10)
|
||||
web += "<td>[MINESWEEPERIMG(minehit)]</td>"
|
||||
if(11)
|
||||
web += "<td>[MINESWEEPERIMG(empty)]</td>"
|
||||
if(12)
|
||||
web += "<td>[MINESWEEPERIMG(1)]</td>"
|
||||
if(13)
|
||||
web += "<td>[MINESWEEPERIMG(2)]</td>"
|
||||
if(14)
|
||||
web += "<td>[MINESWEEPERIMG(3)]</td>"
|
||||
if(15)
|
||||
web += "<td>[MINESWEEPERIMG(4)]</td>"
|
||||
if(16)
|
||||
web += "<td>[MINESWEEPERIMG(5)]</td>"
|
||||
if(17)
|
||||
web += "<td>[MINESWEEPERIMG(6)]</td>"
|
||||
if(18)
|
||||
web += "<td>[MINESWEEPERIMG(7)]</td>"
|
||||
if(19)
|
||||
web += "<td>[MINESWEEPERIMG(8)]</td>"
|
||||
web += "</tr>"
|
||||
web += "</table>"
|
||||
web += "</tbody>"
|
||||
web += "<br>"
|
||||
|
||||
if(safe_squares_revealed >= win_condition && game_status == MINESWEEPER_GAME_PLAYING)
|
||||
game_status = MINESWEEPER_GAME_WON
|
||||
if(rows < 10 || columns < 10) //If less than easy difficulty
|
||||
playsound(loc, 'sound/arcade/minesweeper_winfail.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
say("You cleared the board of all mines, but you picked too small of a board! Try again with at least a 9x9 board!")
|
||||
else
|
||||
playsound(loc, 'sound/arcade/minesweeper_win.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
say("You cleared the board of all mines! Congratulations!")
|
||||
if(CHECK_BITFIELD(obj_flags, EMAGGED))
|
||||
var/itemname
|
||||
switch(rand(1,3))
|
||||
if(1)
|
||||
itemname = "a syndicate bomb beacon"
|
||||
new /obj/item/sbeacondrop/bomb(loc)
|
||||
if(2)
|
||||
itemname = "a grenade launcher"
|
||||
new /obj/item/gun/ballistic/revolver/grenadelauncher/unrestricted(loc)
|
||||
new /obj/item/ammo_casing/a40mm(loc)
|
||||
new /obj/item/ammo_casing/a40mm(loc)
|
||||
new /obj/item/ammo_casing/a40mm(loc)
|
||||
if(3)
|
||||
itemname = "two bags of c4"
|
||||
new /obj/item/storage/backpack/duffelbag/syndie/c4(loc)
|
||||
new /obj/item/storage/backpack/duffelbag/syndie/x4(loc)
|
||||
message_admins("[key_name_admin(user)] won emagged Minesweeper and got [itemname]!")
|
||||
visible_message("<span class='notice'>[src] dispenses [itemname]!</span>", "<span class='notice'>You hear a chime and a clunk.</span>")
|
||||
DISABLE_BITFIELD(obj_flags, EMAGGED)
|
||||
else
|
||||
var/dope_prizes = (area >= 480) ? list(ARCADE_WEIGHT_RARE) : (area >= 256) ? list(ARCADE_WEIGHT_RARE, ARCADE_WEIGHT_TRICK) : null
|
||||
prizevend(user, dope_prizes)
|
||||
|
||||
if(game_status == MINESWEEPER_GAME_WON)
|
||||
web += "[(rows < 10 || columns < 10) ? "<font size='4'>You won, but your board was too small! Pick a bigger board next time!" : "<font size='6'>Congratulations, you have won!"]<br><font size='3'>Want to play again?<br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font></a></b><br><a href='byond://?src=[REF(src)];same_board=1'><font color='#cc66ff'>Play on the same board</font></a><br><a href='byond://?src=[REF(src)];Main_Menu=1'><font color='#cc66ff'>Return to Main Menu</font></a></b><br>"
|
||||
|
||||
if(game_status == MINESWEEPER_GAME_LOST)
|
||||
web += "<font size='6'>You have lost!<br><font size='3'>Try again?<br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font></a></b><br><a href='byond://?src=[REF(src)];same_board=1'><font color='#cc66ff'>Play on the same board</font></a><br><a href='byond://?src=[REF(src)];Main_Menu=1'><font color='#cc66ff'>Return to Main Menu</font></a></b><br>"
|
||||
|
||||
if(game_status == MINESWEEPER_GAME_PLAYING)
|
||||
web += "<a href='byond://?src=[REF(src)];Main_Menu=1'><font color='#cc66ff'>Return to Main Menu</font></a><br>"
|
||||
web += "<div align='right'>Difficulty: [difficulty]<br>Mines: [mine_placed]<br>Rows: [rows-1]<br>Columns: [columns-1]<br><a href='byond://?src=[REF(src)];Flag=1'><font color='#cc66ff'>Flagging mode: [flag_text]</font></a></div>"
|
||||
|
||||
web += "</div>"
|
||||
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/minesweeper)
|
||||
saved_web = sheet.css_tag()
|
||||
saved_web += web
|
||||
updateDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/arcade/minesweeper/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(CHECK_BITFIELD(obj_flags, EMAGGED))
|
||||
return
|
||||
desc = "An arcade machine that generates grids. It's clunking and sparking everywhere, almost as if threatening to explode at any moment!"
|
||||
do_sparks(5, 1, src)
|
||||
randomnumber = rand(1,255)
|
||||
randomcolour = rgb(randomnumber,randomnumber/2,randomnumber/3)
|
||||
ENABLE_BITFIELD(obj_flags, EMAGGED)
|
||||
if(game_status == MINESWEEPER_GAME_MAIN_MENU)
|
||||
to_chat(user, "<span class='warning'>An ominous tune plays from the arcade's speakers!</span>")
|
||||
playsound(user, 'sound/arcade/minesweeper_emag1.ogg', 100, 0, extrarange = 3, falloff = 10)
|
||||
else //Can't let you do that, star fox!
|
||||
to_chat(user, "<span class='warning'>The machine buzzes and sparks... the game has been reset!</span>")
|
||||
playsound(user, 'sound/machines/buzz-sigh.ogg', 100, 0, extrarange = 3, falloff = 10) //Loud buzz
|
||||
game_status = MINESWEEPER_GAME_MAIN_MENU
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/arcade/minesweeper/proc/custom_generation(mob/user)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) //Entered into the menu so ping sound
|
||||
var/new_rows = input(user, "How many rows do you want? (Minimum: 4, Maximum: 30)", "Minesweeper Rows") as null|num
|
||||
if(!new_rows || !user.canUseTopic(src, !issilicon(user)))
|
||||
return FALSE
|
||||
new_rows = CLAMP(new_rows + 1, 4, 30)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
var/new_columns = input(user, "How many columns do you want? (Minimum: 4, Maximum: 50)", "Minesweeper Squares") as null|num
|
||||
if(!new_columns || !user.canUseTopic(src, !issilicon(user)))
|
||||
return FALSE
|
||||
new_columns = CLAMP(new_columns + 1, 4, 50)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
var/grid_area = (new_rows - 1) * (new_columns - 1)
|
||||
var/lower_limit = round(grid_area*0.156)
|
||||
var/upper_limit = round(grid_area*0.85)
|
||||
var/new_mine_limit = input(user, "How many mines do you want? (Minimum: [lower_limit], Maximum: [upper_limit])", "Minesweeper Mines") as null|num
|
||||
if(!new_mine_limit || !user.canUseTopic(src, !issilicon(user)))
|
||||
return FALSE
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
rows = new_rows
|
||||
columns = new_columns
|
||||
mine_limit = CLAMP(new_mine_limit, lower_limit, upper_limit)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/arcade/minesweeper/proc/make_mines(var/reset_everything)
|
||||
if(mine_placed < mine_limit)
|
||||
for(var/y1=1;y1<rows;y1++) //Board resetting and mine building
|
||||
for(var/x1=1;x1<columns;x1++)
|
||||
if(prob(area/mine_limit) && mine_placed < mine_limit && table[y1][x1] != 0) //Unlikely for this to happen but this has eaten mines before
|
||||
table[y1][x1] = 0
|
||||
mine_placed += 1
|
||||
else if(reset_everything)
|
||||
table[y1][x1] = 1
|
||||
reset_everything = FALSE
|
||||
make_mines() //In case the first pass doesn't generate enough mines
|
||||
|
||||
/obj/machinery/computer/arcade/minesweeper/proc/work_squares(var/y2, var/x2, var/y3, var/x3)
|
||||
if(y3 > 0 && x3 > 0)
|
||||
y2 = y3
|
||||
x2 = x3
|
||||
if(table[y2][x2] == 1)
|
||||
for(y3=y2-1;y3<y2+2;y3++)
|
||||
if(y3 >= rows || y3 < 1)
|
||||
continue
|
||||
for(x3=x2-1;x3<x2+2;x3++)
|
||||
if(x3 >= columns || x3 < 1)
|
||||
continue
|
||||
if(table[y3][x3] == 0)
|
||||
table[y2][x2] += 1
|
||||
if(table[y2][x2] == 11)
|
||||
for(y3=y2-1;y3<y2+2;y3++)
|
||||
if(y3 >= rows || y3 < 1)
|
||||
continue
|
||||
for(x3=x2-1;x3<x2+2;x3++)
|
||||
if(x3 >= columns || x3 < 1)
|
||||
continue
|
||||
if(table[y3][x3] > 0 && table[y3][x3] < 10)
|
||||
table[y3][x3] += 10
|
||||
work_squares(y3, x3) //Refresh so we check everything we might be missing
|
||||
|
||||
/obj/machinery/computer/arcade/minesweeper/proc/explode_EVERYTHING()
|
||||
var/mob/living/user = usr
|
||||
to_chat(user, "<span class='boldwarning'>You feel a great sense of dread wash over you, as if you just unleashed armageddon upon yourself!</span>")
|
||||
var/row_limit = rows-1
|
||||
var/column_limit = columns-1
|
||||
var/mine_limit_v2 = mine_limit
|
||||
if(rows > 11)
|
||||
row_limit = 10
|
||||
if(columns > 11)
|
||||
column_limit = 10
|
||||
if(mine_limit > (rows*columns) * 0.25)
|
||||
mine_limit_v2 = 24
|
||||
message_admins("[key_name_admin(user)] failed an emagged Minesweeper arcade and has unleashed an explosion armageddon of size [row_limit],[column_limit] around [ADMIN_LOOKUPFLW(user.loc)]!")
|
||||
if(mine_limit_v2 < 10)
|
||||
explosion(loc, 2, 5, 10, 15) //Thought you could survive by putting as few mines as possible, huh??
|
||||
else
|
||||
explosion(loc, 1, 3, rand(1,5), rand(1,10))
|
||||
for(var/y69=y-row_limit;y69<y+row_limit;y69++) //Create a shitton of explosions in irl turfs if we lose, it will probably kill us
|
||||
for(var/x69=x-column_limit;x69<x+column_limit;x69++)
|
||||
if(prob(mine_limit_v2)) //Probability of explosion happening, according to how many mines were on the board... up to a limit
|
||||
var/explosionloc
|
||||
explosionloc = locate(y69,x69,z)
|
||||
explosion(explosionloc, 0, rand(1,2),rand(1,5),rand(3,10), adminlog = FALSE)
|
||||
|
||||
#undef MINESWEEPERIMG
|
||||
#undef MINESWEEPER_GAME_MAIN_MENU
|
||||
#undef MINESWEEPER_GAME_PLAYING
|
||||
#undef MINESWEEPER_GAME_LOST
|
||||
#undef MINESWEEPER_GAME_WON
|
||||
31
code/game/machinery/computer/arcade/misc_arcade.dm
Normal file
31
code/game/machinery/computer/arcade/misc_arcade.dm
Normal file
@@ -0,0 +1,31 @@
|
||||
// Memeorable yet too short arcade games ahead.
|
||||
|
||||
// ** AMPUTATION ** //
|
||||
|
||||
/obj/machinery/computer/arcade/amputation
|
||||
name = "Mediborg's Amputation Adventure"
|
||||
desc = "A picture of a blood-soaked medical cyborg flashes on the screen. The mediborg has a speech bubble that says, \"Put your hand in the machine if you aren't a <b>coward!</b>\""
|
||||
icon_state = "arcade"
|
||||
circuit = /obj/item/circuitboard/computer/arcade/amputation
|
||||
|
||||
/obj/machinery/computer/arcade/amputation/attack_hand(mob/user)
|
||||
if(!iscarbon(user))
|
||||
return
|
||||
var/mob/living/carbon/c_user = user
|
||||
if(!c_user.get_bodypart(BODY_ZONE_L_ARM) && !c_user.get_bodypart(BODY_ZONE_R_ARM))
|
||||
return
|
||||
to_chat(c_user, "<span class='warning'>You move your hand towards the machine, and begin to hesitate as a bloodied guillotine emerges from inside of it...</span>")
|
||||
if(do_after(c_user, 50, target = src))
|
||||
to_chat(c_user, "<span class='userdanger'>The guillotine drops on your arm, and the machine sucks it in!</span>")
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
var/which_hand = BODY_ZONE_L_ARM
|
||||
if(!(c_user.active_hand_index % 2))
|
||||
which_hand = BODY_ZONE_R_ARM
|
||||
var/obj/item/bodypart/chopchop = c_user.get_bodypart(which_hand)
|
||||
chopchop.dismember()
|
||||
qdel(chopchop)
|
||||
playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
for(var/i=1; i<=rand(3,5); i++)
|
||||
prizevend(user)
|
||||
else
|
||||
to_chat(c_user, "<span class='notice'>You (wisely) decide against putting your hand in the machine.</span>")
|
||||
811
code/game/machinery/computer/arcade/orion_trail.dm
Normal file
811
code/game/machinery/computer/arcade/orion_trail.dm
Normal file
@@ -0,0 +1,811 @@
|
||||
|
||||
|
||||
// *** THE ORION TRAIL ** //
|
||||
|
||||
#define ORION_TRAIL_WINTURN 9
|
||||
|
||||
//Orion Trail Events
|
||||
#define ORION_TRAIL_RAIDERS "Raiders"
|
||||
#define ORION_TRAIL_FLUX "Interstellar Flux"
|
||||
#define ORION_TRAIL_ILLNESS "Illness"
|
||||
#define ORION_TRAIL_BREAKDOWN "Breakdown"
|
||||
#define ORION_TRAIL_LING "Changelings?"
|
||||
#define ORION_TRAIL_LING_ATTACK "Changeling Ambush"
|
||||
#define ORION_TRAIL_MALFUNCTION "Malfunction"
|
||||
#define ORION_TRAIL_COLLISION "Collision"
|
||||
#define ORION_TRAIL_SPACEPORT "Spaceport"
|
||||
#define ORION_TRAIL_BLACKHOLE "BlackHole"
|
||||
|
||||
#define ORION_STATUS_START 1
|
||||
#define ORION_STATUS_NORMAL 2
|
||||
#define ORION_STATUS_GAMEOVER 3
|
||||
#define ORION_STATUS_MARKET 4
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail
|
||||
name = "The Orion Trail"
|
||||
desc = "Learn how our ancestors got to Orion, and have fun in the process!"
|
||||
icon_state = "arcade"
|
||||
circuit = /obj/item/circuitboard/computer/arcade/orion_trail
|
||||
var/busy = FALSE //prevent clickspam that allowed people to ~speedrun~ the game.
|
||||
var/engine = 0
|
||||
var/hull = 0
|
||||
var/electronics = 0
|
||||
var/food = 80
|
||||
var/fuel = 60
|
||||
var/turns = 4
|
||||
var/alive = 4
|
||||
var/eventdat = null
|
||||
var/event = null
|
||||
var/list/settlers = list("Harry","Larry","Bob")
|
||||
var/list/events = list(ORION_TRAIL_RAIDERS = 3,
|
||||
ORION_TRAIL_FLUX = 1,
|
||||
ORION_TRAIL_ILLNESS = 3,
|
||||
ORION_TRAIL_BREAKDOWN = 2,
|
||||
ORION_TRAIL_LING = 3,
|
||||
ORION_TRAIL_MALFUNCTION = 2,
|
||||
ORION_TRAIL_COLLISION = 1,
|
||||
ORION_TRAIL_SPACEPORT = 2
|
||||
)
|
||||
var/list/stops = list()
|
||||
var/list/stopblurbs = list()
|
||||
var/lings_aboard = 0
|
||||
var/spaceport_raided = 0
|
||||
var/spaceport_freebie = 0
|
||||
var/last_spaceport_action = ""
|
||||
var/gameStatus = ORION_STATUS_START
|
||||
var/canContinueEvent = 0
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/kobayashi
|
||||
name = "Kobayashi Maru control computer"
|
||||
desc = "A test for cadets"
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "control_boxp"
|
||||
events = list("Raiders" = 3, "Interstellar Flux" = 1, "Illness" = 3, "Breakdown" = 2, "Malfunction" = 2, "Collision" = 1, "Spaceport" = 2)
|
||||
prizes = list(/obj/item/paper/fluff/holodeck/trek_diploma = 1)
|
||||
settlers = list("Kirk","Worf","Gene")
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/Reset()
|
||||
// Sets up the main trail
|
||||
stops = list("Pluto","Asteroid Belt","Proxima Centauri","Dead Space","Rigel Prime","Tau Ceti Beta","Black Hole","Space Outpost Beta-9","Orion Prime")
|
||||
stopblurbs = list(
|
||||
"Pluto, long since occupied with long-range sensors and scanners, stands ready to, and indeed continues to probe the far reaches of the galaxy.",
|
||||
"At the edge of the Sol system lies a treacherous asteroid belt. Many have been crushed by stray asteroids and misguided judgement.",
|
||||
"The nearest star system to Sol, in ages past it stood as a reminder of the boundaries of sub-light travel, now a low-population sanctuary for adventurers and traders.",
|
||||
"This region of space is particularly devoid of matter. Such low-density pockets are known to exist, but the vastness of it is astounding.",
|
||||
"Rigel Prime, the center of the Rigel system, burns hot, basking its planetary bodies in warmth and radiation.",
|
||||
"Tau Ceti Beta has recently become a waypoint for colonists headed towards Orion. There are many ships and makeshift stations in the vicinity.",
|
||||
"Sensors indicate that a black hole's gravitational field is affecting the region of space we were headed through. We could stay of course, but risk of being overcome by its gravity, or we could change course to go around, which will take longer.",
|
||||
"You have come into range of the first man-made structure in this region of space. It has been constructed not by travellers from Sol, but by colonists from Orion. It stands as a monument to the colonists' success.",
|
||||
"You have made it to Orion! Congratulations! Your crew is one of the few to start a new foothold for mankind!"
|
||||
)
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/proc/newgame()
|
||||
// Set names of settlers in crew
|
||||
settlers = list()
|
||||
for(var/i = 1; i <= 3; i++)
|
||||
add_crewmember()
|
||||
add_crewmember("[usr]")
|
||||
// Re-set items to defaults
|
||||
engine = 1
|
||||
hull = 1
|
||||
electronics = 1
|
||||
food = 80
|
||||
fuel = 60
|
||||
alive = 4
|
||||
turns = 1
|
||||
event = null
|
||||
gameStatus = ORION_STATUS_NORMAL
|
||||
lings_aboard = 0
|
||||
|
||||
//spaceport junk
|
||||
spaceport_raided = 0
|
||||
spaceport_freebie = 0
|
||||
last_spaceport_action = ""
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/ui_interact(mob/user)
|
||||
. = ..()
|
||||
if(fuel <= 0 || food <=0 || settlers.len == 0)
|
||||
gameStatus = ORION_STATUS_GAMEOVER
|
||||
event = null
|
||||
var/dat = ""
|
||||
if(gameStatus == ORION_STATUS_GAMEOVER)
|
||||
dat = "<center><h1>Game Over</h1></center>"
|
||||
dat += "Like many before you, your crew never made it to Orion, lost to space... <br><b>Forever</b>."
|
||||
if(!settlers.len)
|
||||
dat += "<br>Your entire crew died, and your ship joins the fleet of ghost-ships littering the galaxy."
|
||||
else
|
||||
if(food <= 0)
|
||||
dat += "<br>You ran out of food and starved."
|
||||
if(obj_flags & EMAGGED)
|
||||
user.nutrition = 0 //yeah you pretty hongry
|
||||
to_chat(user, "<span class='userdanger'>Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor.</span>")
|
||||
if(fuel <= 0)
|
||||
dat += "<br>You ran out of fuel, and drift, slowly, into a star."
|
||||
if(obj_flags & EMAGGED)
|
||||
var/mob/living/M = user
|
||||
M.adjust_fire_stacks(5)
|
||||
M.IgniteMob() //flew into a star, so you're on fire
|
||||
to_chat(user, "<span class='userdanger'>You feel an immense wave of heat emanate from the arcade machine. Your skin bursts into flames.</span>")
|
||||
|
||||
if(obj_flags & EMAGGED)
|
||||
to_chat(user, "<span class='userdanger'>You're never going to make it to Orion...</span>")
|
||||
user.death()
|
||||
obj_flags &= ~EMAGGED //removes the emagged status after you lose
|
||||
gameStatus = ORION_STATUS_START
|
||||
name = "The Orion Trail"
|
||||
desc = "Learn how our ancestors got to Orion, and have fun in the process!"
|
||||
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];menu=1'>May They Rest In Peace</a></P>"
|
||||
else if(event)
|
||||
dat = eventdat
|
||||
else if(gameStatus == ORION_STATUS_NORMAL)
|
||||
var/title = stops[turns]
|
||||
var/subtext = stopblurbs[turns]
|
||||
dat = "<center><h1>[title]</h1></center>"
|
||||
dat += "[subtext]"
|
||||
dat += "<h3><b>Crew:</b></h3>"
|
||||
dat += english_list(settlers)
|
||||
dat += "<br><b>Food: </b>[food] | <b>Fuel: </b>[fuel]"
|
||||
dat += "<br><b>Engine Parts: </b>[engine] | <b>Hull Panels: </b>[hull] | <b>Electronics: </b>[electronics]"
|
||||
if(turns == 7)
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];pastblack=1'>Go Around</a> <a href='byond://?src=[REF(src)];blackhole=1'>Continue</a></P>"
|
||||
else
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];continue=1'>Continue</a></P>"
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];killcrew=1'>Kill a Crewmember</a></P>"
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
else
|
||||
dat = "<center><h2>The Orion Trail</h2></center>"
|
||||
dat += "<br><center><h3>Experience the journey of your ancestors!</h3></center><br><br>"
|
||||
dat += "<center><b><a href='byond://?src=[REF(src)];newgame=1'>New Game</a></b></center>"
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
var/datum/browser/popup = new(user, "arcade", "The Orion Trail",400,700)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
popup.open()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
if(href_list["close"])
|
||||
usr.unset_machine()
|
||||
usr << browse(null, "window=arcade")
|
||||
|
||||
if(busy)
|
||||
return
|
||||
busy = TRUE
|
||||
|
||||
if (href_list["continue"]) //Continue your travels
|
||||
if(gameStatus == ORION_STATUS_NORMAL && !event && turns != 7)
|
||||
if(turns >= ORION_TRAIL_WINTURN)
|
||||
win(usr)
|
||||
else
|
||||
food -= (alive+lings_aboard)*2
|
||||
fuel -= 5
|
||||
if(turns == 2 && prob(30))
|
||||
event = ORION_TRAIL_COLLISION
|
||||
event()
|
||||
else if(prob(75))
|
||||
event = pickweight(events)
|
||||
if(lings_aboard)
|
||||
if(event == ORION_TRAIL_LING || prob(55))
|
||||
event = ORION_TRAIL_LING_ATTACK
|
||||
event()
|
||||
turns += 1
|
||||
if(obj_flags & EMAGGED)
|
||||
var/mob/living/carbon/M = usr //for some vars
|
||||
switch(event)
|
||||
if(ORION_TRAIL_RAIDERS)
|
||||
if(prob(50))
|
||||
to_chat(usr, "<span class='userdanger'>You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?</span>")
|
||||
M.hallucination += 30
|
||||
else
|
||||
to_chat(usr, "<span class='userdanger'>Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there...</span>")
|
||||
M.take_bodypart_damage(30)
|
||||
playsound(loc, 'sound/weapons/genhit2.ogg', 100, 1)
|
||||
if(ORION_TRAIL_ILLNESS)
|
||||
var/severity = rand(1,3) //pray to RNGesus. PRAY, PIGS
|
||||
if(severity == 1)
|
||||
to_chat(M, "<span class='userdanger'>You suddenly feel slightly nauseated.</span>" )
|
||||
if(severity == 2)
|
||||
to_chat(usr, "<span class='userdanger'>You suddenly feel extremely nauseated and hunch over until it passes.</span>")
|
||||
M.Stun(60)
|
||||
if(severity >= 3) //you didn't pray hard enough
|
||||
to_chat(M, "<span class='warning'>An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit.</span>")
|
||||
M.Stun(100)
|
||||
sleep(30)
|
||||
M.vomit(10, distance = 5)
|
||||
if(ORION_TRAIL_FLUX)
|
||||
if(prob(75))
|
||||
M.Knockdown(60)
|
||||
say("A sudden gust of powerful wind slams [M] into the floor!")
|
||||
M.take_bodypart_damage(25)
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 100, 1)
|
||||
else
|
||||
to_chat(M, "<span class='userdanger'>A violent gale blows past you, and you barely manage to stay standing!</span>")
|
||||
if(ORION_TRAIL_COLLISION) //by far the most damaging event
|
||||
if(prob(90))
|
||||
playsound(loc, 'sound/effects/bang.ogg', 100, 1)
|
||||
var/turf/open/floor/F
|
||||
for(F in orange(1, src))
|
||||
F.ScrapeAway()
|
||||
say("Something slams into the floor around [src], exposing it to space!")
|
||||
if(hull)
|
||||
sleep(10)
|
||||
say("A new floor suddenly appears around [src]. What the hell?")
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 100, 1)
|
||||
var/turf/open/space/T
|
||||
for(T in orange(1, src))
|
||||
T.PlaceOnTop(/turf/open/floor/plating)
|
||||
else
|
||||
say("Something slams into the floor around [src] - luckily, it didn't get through!")
|
||||
playsound(loc, 'sound/effects/bang.ogg', 50, 1)
|
||||
if(ORION_TRAIL_MALFUNCTION)
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 50, 1)
|
||||
visible_message("<span class='danger'>[src] malfunctions, randomizing in-game stats!</span>")
|
||||
var/oldfood = food
|
||||
var/oldfuel = fuel
|
||||
food = rand(10,80) / rand(1,2)
|
||||
fuel = rand(10,60) / rand(1,2)
|
||||
if(electronics)
|
||||
sleep(10)
|
||||
if(oldfuel > fuel && oldfood > food)
|
||||
audible_message("<span class='danger'>[src] lets out a somehow reassuring chime.</span>")
|
||||
else if(oldfuel < fuel || oldfood < food)
|
||||
audible_message("<span class='danger'>[src] lets out a somehow ominous chime.</span>")
|
||||
food = oldfood
|
||||
fuel = oldfuel
|
||||
playsound(loc, 'sound/machines/chime.ogg', 50, 1)
|
||||
|
||||
else if(href_list["newgame"]) //Reset everything
|
||||
if(gameStatus == ORION_STATUS_START)
|
||||
newgame()
|
||||
else if(href_list["menu"]) //back to the main menu
|
||||
if(gameStatus == ORION_STATUS_GAMEOVER)
|
||||
gameStatus = ORION_STATUS_START
|
||||
event = null
|
||||
food = 80
|
||||
fuel = 60
|
||||
settlers = list("Harry","Larry","Bob")
|
||||
else if(href_list["slow"]) //slow down
|
||||
if(event == ORION_TRAIL_FLUX)
|
||||
food -= (alive+lings_aboard)*2
|
||||
fuel -= 5
|
||||
event = null
|
||||
else if(href_list["pastblack"]) //slow down
|
||||
if(turns == 7)
|
||||
food -= ((alive+lings_aboard)*2)*3
|
||||
fuel -= 15
|
||||
turns += 1
|
||||
event = null
|
||||
else if(href_list["useengine"]) //use parts
|
||||
if(event == ORION_TRAIL_BREAKDOWN)
|
||||
engine = max(0, --engine)
|
||||
event = null
|
||||
else if(href_list["useelec"]) //use parts
|
||||
if(event == ORION_TRAIL_MALFUNCTION)
|
||||
electronics = max(0, --electronics)
|
||||
event = null
|
||||
else if(href_list["usehull"]) //use parts
|
||||
if(event == ORION_TRAIL_COLLISION)
|
||||
hull = max(0, --hull)
|
||||
event = null
|
||||
else if(href_list["wait"]) //wait 3 days
|
||||
if(event == ORION_TRAIL_BREAKDOWN || event == ORION_TRAIL_MALFUNCTION || event == ORION_TRAIL_COLLISION)
|
||||
food -= ((alive+lings_aboard)*2)*3
|
||||
event = null
|
||||
else if(href_list["keepspeed"]) //keep speed
|
||||
if(event == ORION_TRAIL_FLUX)
|
||||
if(prob(75))
|
||||
event = "Breakdown"
|
||||
event()
|
||||
else
|
||||
event = null
|
||||
else if(href_list["blackhole"]) //keep speed past a black hole
|
||||
if(turns == 7)
|
||||
if(prob(75))
|
||||
event = ORION_TRAIL_BLACKHOLE
|
||||
event()
|
||||
if(obj_flags & EMAGGED)
|
||||
playsound(loc, 'sound/effects/supermatter.ogg', 100, 1)
|
||||
say("A miniature black hole suddenly appears in front of [src], devouring [usr] alive!")
|
||||
if(isliving(usr))
|
||||
var/mob/living/L = usr
|
||||
L.Stun(200, ignore_canstun = TRUE) //you can't run :^)
|
||||
var/S = new /obj/singularity/academy(usr.loc)
|
||||
addtimer(CALLBACK(src, /atom/movable/proc/say, "[S] winks out, just as suddenly as it appeared."), 50)
|
||||
QDEL_IN(S, 50)
|
||||
else
|
||||
event = null
|
||||
turns += 1
|
||||
else if(href_list["holedeath"])
|
||||
if(event == ORION_TRAIL_BLACKHOLE)
|
||||
gameStatus = ORION_STATUS_GAMEOVER
|
||||
event = null
|
||||
else if(href_list["eventclose"]) //end an event
|
||||
if(canContinueEvent)
|
||||
event = null
|
||||
|
||||
else if(href_list["killcrew"]) //shoot a crewmember
|
||||
if(gameStatus == ORION_STATUS_NORMAL || event == ORION_TRAIL_LING)
|
||||
var/sheriff = remove_crewmember() //I shot the sheriff
|
||||
playsound(loc,'sound/weapons/gunshot.ogg', 100, 1)
|
||||
|
||||
if(settlers.len == 0 || alive == 0)
|
||||
say("The last crewmember [sheriff], shot themselves, GAME OVER!")
|
||||
if(obj_flags & EMAGGED)
|
||||
usr.death(0)
|
||||
obj_flags &= EMAGGED
|
||||
gameStatus = ORION_STATUS_GAMEOVER
|
||||
event = null
|
||||
else if(obj_flags & EMAGGED)
|
||||
if(usr.name == sheriff)
|
||||
say("The crew of the ship chose to kill [usr.name]!")
|
||||
usr.death(0)
|
||||
|
||||
if(event == ORION_TRAIL_LING) //only ends the ORION_TRAIL_LING event, since you can do this action in multiple places
|
||||
event = null
|
||||
|
||||
//Spaceport specific interactions
|
||||
//they get a header because most of them don't reset event (because it's a shop, you leave when you want to)
|
||||
//they also call event() again, to regen the eventdata, which is kind of odd but necessary
|
||||
else if(href_list["buycrew"]) //buy a crewmember
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
if(!spaceport_raided && food >= 10 && fuel >= 10)
|
||||
var/bought = add_crewmember()
|
||||
last_spaceport_action = "You hired [bought] as a new crewmember."
|
||||
fuel -= 10
|
||||
food -= 10
|
||||
event()
|
||||
|
||||
else if(href_list["sellcrew"]) //sell a crewmember
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
if(!spaceport_raided && settlers.len > 1)
|
||||
var/sold = remove_crewmember()
|
||||
last_spaceport_action = "You sold your crewmember, [sold]!"
|
||||
fuel += 7
|
||||
food += 7
|
||||
event()
|
||||
|
||||
else if(href_list["leave_spaceport"])
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
event = null
|
||||
gameStatus = ORION_STATUS_NORMAL
|
||||
spaceport_raided = 0
|
||||
spaceport_freebie = 0
|
||||
last_spaceport_action = ""
|
||||
|
||||
else if(href_list["raid_spaceport"])
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
if(!spaceport_raided)
|
||||
var/success = min(15 * alive,100) //default crew (4) have a 60% chance
|
||||
spaceport_raided = 1
|
||||
|
||||
var/FU = 0
|
||||
var/FO = 0
|
||||
if(prob(success))
|
||||
FU = rand(5,15)
|
||||
FO = rand(5,15)
|
||||
last_spaceport_action = "You successfully raided the spaceport! You gained [FU] Fuel and [FO] Food! (+[FU]FU,+[FO]FO)"
|
||||
else
|
||||
FU = rand(-5,-15)
|
||||
FO = rand(-5,-15)
|
||||
last_spaceport_action = "You failed to raid the spaceport! You lost [FU*-1] Fuel and [FO*-1] Food in your scramble to escape! ([FU]FU,[FO]FO)"
|
||||
|
||||
//your chance of lose a crewmember is 1/2 your chance of success
|
||||
//this makes higher % failures hurt more, don't get cocky space cowboy!
|
||||
if(prob(success*5))
|
||||
var/lost_crew = remove_crewmember()
|
||||
last_spaceport_action = "You failed to raid the spaceport! You lost [FU*-1] Fuel and [FO*-1] Food, AND [lost_crew] in your scramble to escape! ([FU]FI,[FO]FO,-Crew)"
|
||||
if(obj_flags & EMAGGED)
|
||||
say("WEEWOO! WEEWOO! Spaceport security en route!")
|
||||
playsound(src, 'sound/items/weeoo1.ogg', 100, FALSE)
|
||||
for(var/i, i<=3, i++)
|
||||
var/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion/O = new/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion(get_turf(src))
|
||||
O.target = usr
|
||||
|
||||
|
||||
fuel += FU
|
||||
food += FO
|
||||
event()
|
||||
|
||||
else if(href_list["buyparts"])
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
if(!spaceport_raided && fuel > 5)
|
||||
switch(text2num(href_list["buyparts"]))
|
||||
if(1) //Engine Parts
|
||||
engine++
|
||||
last_spaceport_action = "Bought Engine Parts"
|
||||
if(2) //Hull Plates
|
||||
hull++
|
||||
last_spaceport_action = "Bought Hull Plates"
|
||||
if(3) //Spare Electronics
|
||||
electronics++
|
||||
last_spaceport_action = "Bought Spare Electronics"
|
||||
fuel -= 5 //they all cost 5
|
||||
event()
|
||||
|
||||
else if(href_list["trade"])
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
if(!spaceport_raided)
|
||||
switch(text2num(href_list["trade"]))
|
||||
if(1) //Fuel
|
||||
if(fuel > 5)
|
||||
fuel -= 5
|
||||
food += 5
|
||||
last_spaceport_action = "Traded Fuel for Food"
|
||||
event()
|
||||
if(2) //Food
|
||||
if(food > 5)
|
||||
fuel += 5
|
||||
food -= 5
|
||||
last_spaceport_action = "Traded Food for Fuel"
|
||||
event()
|
||||
|
||||
add_fingerprint(usr)
|
||||
updateUsrDialog()
|
||||
busy = FALSE
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/proc/event()
|
||||
eventdat = "<center><h1>[event]</h1></center>"
|
||||
canContinueEvent = 0
|
||||
switch(event)
|
||||
if(ORION_TRAIL_RAIDERS)
|
||||
eventdat += "Raiders have come aboard your ship!"
|
||||
if(prob(50))
|
||||
var/sfood = rand(1,10)
|
||||
var/sfuel = rand(1,10)
|
||||
food -= sfood
|
||||
fuel -= sfuel
|
||||
eventdat += "<br>They have stolen [sfood] <b>Food</b> and [sfuel] <b>Fuel</b>."
|
||||
else if(prob(10))
|
||||
var/deadname = remove_crewmember()
|
||||
eventdat += "<br>[deadname] tried to fight back, but was killed."
|
||||
else
|
||||
eventdat += "<br>Fortunately, you fended them off without any trouble."
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
if(ORION_TRAIL_FLUX)
|
||||
eventdat += "This region of space is highly turbulent. <br>If we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies."
|
||||
eventdat += "<br>What will you do?"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];slow=1'>Slow Down</a> <a href='byond://?src=[REF(src)];keepspeed=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
|
||||
if(ORION_TRAIL_ILLNESS)
|
||||
eventdat += "A deadly illness has been contracted!"
|
||||
var/deadname = remove_crewmember()
|
||||
eventdat += "<br>[deadname] was killed by the disease."
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
if(ORION_TRAIL_BREAKDOWN)
|
||||
eventdat += "Oh no! The engine has broken down!"
|
||||
eventdat += "<br>You can repair it with an engine part, or you can make repairs for 3 days."
|
||||
if(engine >= 1)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];useengine=1'>Use Part</a><a href='byond://?src=[REF(src)];wait=1'>Wait</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];wait=1'>Wait</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
|
||||
if(ORION_TRAIL_MALFUNCTION)
|
||||
eventdat += "The ship's systems are malfunctioning!"
|
||||
eventdat += "<br>You can replace the broken electronics with spares, or you can spend 3 days troubleshooting the AI."
|
||||
if(electronics >= 1)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];useelec=1'>Use Part</a><a href='byond://?src=[REF(src)];wait=1'>Wait</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];wait=1'>Wait</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
|
||||
if(ORION_TRAIL_COLLISION)
|
||||
eventdat += "Something hit us! Looks like there's some hull damage."
|
||||
if(prob(25))
|
||||
var/sfood = rand(5,15)
|
||||
var/sfuel = rand(5,15)
|
||||
food -= sfood
|
||||
fuel -= sfuel
|
||||
eventdat += "<br>[sfood] <b>Food</b> and [sfuel] <b>Fuel</b> was vented out into space."
|
||||
if(prob(10))
|
||||
var/deadname = remove_crewmember()
|
||||
eventdat += "<br>[deadname] was killed by rapid depressurization."
|
||||
eventdat += "<br>You can repair the damage with hull plates, or you can spend the next 3 days welding scrap together."
|
||||
if(hull >= 1)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];usehull=1'>Use Part</a><a href='byond://?src=[REF(src)];wait=1'>Wait</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];wait=1'>Wait</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
|
||||
if(ORION_TRAIL_BLACKHOLE)
|
||||
eventdat += "You were swept away into the black hole."
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];holedeath=1'>Oh...</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
settlers = list()
|
||||
|
||||
if(ORION_TRAIL_LING)
|
||||
eventdat += "Strange reports warn of changelings infiltrating crews on trips to Orion..."
|
||||
if(settlers.len <= 2)
|
||||
eventdat += "<br>Your crew's chance of reaching Orion is so slim the changelings likely avoided your ship..."
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
if(prob(10)) // "likely", I didn't say it was guaranteed!
|
||||
lings_aboard = min(++lings_aboard,2)
|
||||
else
|
||||
if(lings_aboard) //less likely to stack lings
|
||||
if(prob(20))
|
||||
lings_aboard = min(++lings_aboard,2)
|
||||
else if(prob(70))
|
||||
lings_aboard = min(++lings_aboard,2)
|
||||
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];killcrew=1'>Kill a Crewmember</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];eventclose=1'>Risk it</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
if(ORION_TRAIL_LING_ATTACK)
|
||||
if(lings_aboard <= 0) //shouldn't trigger, but hey.
|
||||
eventdat += "Haha, fooled you, there are no changelings on board!"
|
||||
eventdat += "<br>(You should report this to a coder :S)"
|
||||
else
|
||||
var/ling1 = remove_crewmember()
|
||||
var/ling2 = ""
|
||||
if(lings_aboard >= 2)
|
||||
ling2 = remove_crewmember()
|
||||
|
||||
eventdat += "Changelings among your crew suddenly burst from hiding and attack!"
|
||||
if(ling2)
|
||||
eventdat += "<br>[ling1] and [ling2]'s arms twist and contort into grotesque blades!"
|
||||
else
|
||||
eventdat += "<br>[ling1]'s arm twists and contorts into a grotesque blade!"
|
||||
|
||||
var/chance2attack = alive*20
|
||||
if(prob(chance2attack))
|
||||
var/chancetokill = 30*lings_aboard-(5*alive) //eg: 30*2-(10) = 50%, 2 lings, 2 crew is 50% chance
|
||||
if(prob(chancetokill))
|
||||
var/deadguy = remove_crewmember()
|
||||
var/murder_text = pick("The changeling[ling2 ? "s" : ""] bring[ling2 ? "" : "s"] down [deadguy] and disembowel[ling2 ? "" : "s"] them in a spray of gore!", \
|
||||
"[ling2 ? pick(ling1, ling2) : ling1] corners [deadguy] and impales them through the stomach!", \
|
||||
"[ling2 ? pick(ling1, ling2) : ling1] decapitates [deadguy] in a single cleaving arc!")
|
||||
eventdat += "<br>[murder_text]"
|
||||
else
|
||||
eventdat += "<br><br><b>You valiantly fight off the changeling[ling2 ? "s":""]!</b>"
|
||||
if(ling2)
|
||||
food += 30
|
||||
lings_aboard = max(0,lings_aboard-2)
|
||||
else
|
||||
food += 15
|
||||
lings_aboard = max(0,--lings_aboard)
|
||||
eventdat += "<br><i>Well, it's perfectly good food...</i>\
|
||||
<br>You cut the changeling[ling2 ? "s" : ""] into meat, gaining <b>[ling2 ? "30" : "15"]</b> Food!"
|
||||
else
|
||||
eventdat += "<br><br>[pick("Sensing unfavorable odds", "After a failed attack", "Suddenly breaking nerve")], \
|
||||
the changeling[ling2 ? "s":""] vanish[ling2 ? "" : "es"] into space through the airlocks! You're safe... for now."
|
||||
if(ling2)
|
||||
lings_aboard = max(0,lings_aboard-2)
|
||||
else
|
||||
lings_aboard = max(0,--lings_aboard)
|
||||
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
|
||||
if(ORION_TRAIL_SPACEPORT)
|
||||
gameStatus = ORION_STATUS_MARKET
|
||||
if(spaceport_raided)
|
||||
eventdat += "The spaceport is on high alert! You've been barred from docking by the local authorities after your failed raid."
|
||||
if(last_spaceport_action)
|
||||
eventdat += "<br><b>Last Spaceport Action:</b> [last_spaceport_action]"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];leave_spaceport=1'>Depart Spaceport</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
else
|
||||
eventdat += "Your jump into the sector yields a spaceport - a lucky find!"
|
||||
eventdat += "<br>This spaceport is home to travellers who failed to reach Orion, but managed to find a different home..."
|
||||
eventdat += "<br>Trading terms: FU = Fuel, FO = Food"
|
||||
if(last_spaceport_action)
|
||||
eventdat += "<br><b>Last action:</b> [last_spaceport_action]"
|
||||
eventdat += "<h3><b>Crew:</b></h3>"
|
||||
eventdat += english_list(settlers)
|
||||
eventdat += "<br><b>Food: </b>[food] | <b>Fuel: </b>[fuel]"
|
||||
eventdat += "<br><b>Engine Parts: </b>[engine] | <b>Hull Panels: </b>[hull] | <b>Electronics: </b>[electronics]"
|
||||
|
||||
|
||||
//If your crew is pathetic you can get freebies (provided you haven't already gotten one from this port)
|
||||
if(!spaceport_freebie && (fuel < 20 || food < 20))
|
||||
spaceport_freebie++
|
||||
var/FU = 10
|
||||
var/FO = 10
|
||||
var/freecrew = 0
|
||||
if(prob(30))
|
||||
FU = 25
|
||||
FO = 25
|
||||
|
||||
if(prob(10))
|
||||
add_crewmember()
|
||||
freecrew++
|
||||
|
||||
eventdat += "<br>The traders of the spaceport take pity on you, and generously give you some free supplies! (+[FU]FU, +[FO]FO)"
|
||||
if(freecrew)
|
||||
eventdat += "<br>You also gain a new crewmember!"
|
||||
|
||||
fuel += FU
|
||||
food += FO
|
||||
|
||||
//CREW INTERACTIONS
|
||||
eventdat += "<P ALIGN=Right>Crew Management:</P>"
|
||||
|
||||
//Buy crew
|
||||
if(food >= 10 && fuel >= 10)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];buycrew=1'>Hire a New Crewmember (-10FU, -10FO)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You cannot afford a new crewmember.</P>"
|
||||
|
||||
//Sell crew
|
||||
if(settlers.len > 1)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];sellcrew=1'>Sell Crew for Fuel and Food (+7FU, +7FO)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You have no other crew to sell.</P>"
|
||||
|
||||
//BUY/SELL STUFF
|
||||
eventdat += "<P ALIGN=Right>Spare Parts:</P>"
|
||||
|
||||
//Engine parts
|
||||
if(fuel > 5)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];buyparts=1'>Buy Engine Parts (-5FU)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You cannot afford engine parts.</a>"
|
||||
|
||||
//Hull plates
|
||||
if(fuel > 5)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];buyparts=2'>Buy Hull Plates (-5FU)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You cannot afford hull plates.</a>"
|
||||
|
||||
//Electronics
|
||||
if(fuel > 5)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];buyparts=3'>Buy Spare Electronics (-5FU)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You cannot afford spare electronics.</a>"
|
||||
|
||||
//Trade
|
||||
if(fuel > 5)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];trade=1'>Trade Fuel for Food (-5FU,+5FO)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You don't have 5FU to trade.</P"
|
||||
|
||||
if(food > 5)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];trade=2'>Trade Food for Fuel (+5FU,-5FO)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You don't have 5FO to trade.</P"
|
||||
|
||||
//Raid the spaceport
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];raid_spaceport=1'>!! Raid Spaceport !!</a></P>"
|
||||
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];leave_spaceport=1'>Depart Spaceport</a></P>"
|
||||
|
||||
|
||||
//Add Random/Specific crewmember
|
||||
/obj/machinery/computer/arcade/orion_trail/proc/add_crewmember(var/specific = "")
|
||||
var/newcrew = ""
|
||||
if(specific)
|
||||
newcrew = specific
|
||||
else
|
||||
if(prob(50))
|
||||
newcrew = pick(GLOB.first_names_male)
|
||||
else
|
||||
newcrew = pick(GLOB.first_names_female)
|
||||
if(newcrew)
|
||||
settlers += newcrew
|
||||
alive++
|
||||
return newcrew
|
||||
|
||||
|
||||
//Remove Random/Specific crewmember
|
||||
/obj/machinery/computer/arcade/orion_trail/proc/remove_crewmember(var/specific = "", var/dont_remove = "")
|
||||
var/list/safe2remove = settlers
|
||||
var/removed = ""
|
||||
if(dont_remove)
|
||||
safe2remove -= dont_remove
|
||||
if(specific && specific != dont_remove)
|
||||
safe2remove = list(specific)
|
||||
else
|
||||
removed = pick(safe2remove)
|
||||
|
||||
if(removed)
|
||||
if(lings_aboard && prob(40*lings_aboard)) //if there are 2 lings you're twice as likely to get one, obviously
|
||||
lings_aboard = max(0,--lings_aboard)
|
||||
settlers -= removed
|
||||
alive--
|
||||
return removed
|
||||
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/proc/win(mob/user)
|
||||
gameStatus = ORION_STATUS_START
|
||||
say("Congratulations, you made it to Orion!")
|
||||
if(obj_flags & EMAGGED)
|
||||
new /obj/item/orion_ship(loc)
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] made it to Orion on an emagged machine and got an explosive toy ship.")
|
||||
log_game("[key_name(usr)] made it to Orion on an emagged machine and got an explosive toy ship.")
|
||||
else
|
||||
prizevend(user)
|
||||
obj_flags &= ~EMAGGED
|
||||
name = "The Orion Trail"
|
||||
desc = "Learn how our ancestors got to Orion, and have fun in the process!"
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode.</span>")
|
||||
name = "The Orion Trail: Realism Edition"
|
||||
desc = "Learn how our ancestors got to Orion, and try not to die in the process!"
|
||||
newgame()
|
||||
obj_flags |= EMAGGED
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion
|
||||
name = "spaceport security"
|
||||
desc = "Premier corporate security forces for all spaceports found along the Orion Trail."
|
||||
faction = list("orion")
|
||||
loot = list()
|
||||
del_on_death = TRUE
|
||||
|
||||
/obj/item/orion_ship
|
||||
name = "model settler ship"
|
||||
desc = "A model spaceship, it looks like those used back in the day when travelling to Orion! It even has a miniature FX-293 reactor, which was renowned for its instability and tendency to explode..."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "ship"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/active = 0 //if the ship is on
|
||||
|
||||
/obj/item/orion_ship/examine(mob/user)
|
||||
..()
|
||||
if(!(in_range(user, src)))
|
||||
return
|
||||
if(!active)
|
||||
to_chat(user, "<span class='notice'>There's a little switch on the bottom. It's flipped down.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There's a little switch on the bottom. It's flipped up.</span>")
|
||||
|
||||
/obj/item/orion_ship/attack_self(mob/user) //Minibomb-level explosion. Should probably be more because of how hard it is to survive the machine! Also, just over a 5-second fuse
|
||||
if(active)
|
||||
return
|
||||
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] primed an explosive Orion ship for detonation at [AREACOORD(usr)].")
|
||||
log_game("[key_name(usr)] primed an explosive Orion ship for detonation at [AREACOORD(usr)].")
|
||||
|
||||
to_chat(user, "<span class='warning'>You flip the switch on the underside of [src].</span>")
|
||||
active = 1
|
||||
visible_message("<span class='notice'>[src] softly beeps and whirs to life!</span>")
|
||||
playsound(loc, 'sound/machines/defib_SaftyOn.ogg', 25, 1)
|
||||
say("This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.")
|
||||
sleep(20)
|
||||
visible_message("<span class='warning'>[src] begins to vibrate...</span>")
|
||||
say("Uh, Port? Having some issues with our reactor, could you check it out? Over.")
|
||||
sleep(30)
|
||||
say("Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-")
|
||||
playsound(loc, 'sound/machines/buzz-sigh.ogg', 25, 1)
|
||||
sleep(3.6)
|
||||
visible_message("<span class='userdanger'>[src] explodes!</span>")
|
||||
explosion(loc, 2,4,8, flame_range = 16)
|
||||
qdel(src)
|
||||
|
||||
#undef ORION_TRAIL_WINTURN
|
||||
#undef ORION_TRAIL_RAIDERS
|
||||
#undef ORION_TRAIL_FLUX
|
||||
#undef ORION_TRAIL_ILLNESS
|
||||
#undef ORION_TRAIL_BREAKDOWN
|
||||
#undef ORION_TRAIL_LING
|
||||
#undef ORION_TRAIL_LING_ATTACK
|
||||
#undef ORION_TRAIL_MALFUNCTION
|
||||
#undef ORION_TRAIL_COLLISION
|
||||
#undef ORION_TRAIL_SPACEPORT
|
||||
#undef ORION_TRAIL_BLACKHOLE
|
||||
|
||||
#undef ORION_STATUS_START
|
||||
#undef ORION_STATUS_NORMAL
|
||||
#undef ORION_STATUS_GAMEOVER
|
||||
#undef ORION_STATUS_MARKET
|
||||
@@ -214,11 +214,11 @@
|
||||
sparkles += S
|
||||
switch(i)
|
||||
if(1 to 8)
|
||||
S.orbit(src, 30, TRUE, 60, 36, TRUE, FALSE)
|
||||
S.orbit(src, 30, TRUE, 60, 36, TRUE)
|
||||
if(9 to 16)
|
||||
S.orbit(src, 62, TRUE, 60, 36, TRUE, FALSE)
|
||||
S.orbit(src, 62, TRUE, 60, 36, TRUE)
|
||||
if(17 to 24)
|
||||
S.orbit(src, 95, TRUE, 60, 36, TRUE, FALSE)
|
||||
S.orbit(src, 95, TRUE, 60, 36, TRUE)
|
||||
if(25)
|
||||
S.pixel_y = 7
|
||||
S.forceMove(get_turf(src))
|
||||
|
||||
@@ -214,6 +214,7 @@
|
||||
flick("[src.base_state]spark", src)
|
||||
playsound(src, "sparks", 75, 1)
|
||||
addtimer(CALLBACK(src, .proc/open_windows_me), 6)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/door/window/proc/open_windows_me()
|
||||
operating = FALSE
|
||||
|
||||
@@ -214,6 +214,20 @@
|
||||
/obj/item/aiModule/core/full/damaged
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/mre
|
||||
name = "random MRE"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "mre"
|
||||
|
||||
/obj/effect/spawner/lootdrop/mre/Initialize()
|
||||
for(var/A in subtypesof(/obj/item/storage/box/mre))
|
||||
var/obj/item/storage/box/mre/M = A
|
||||
var/our_chance = initial(M.spawner_chance)
|
||||
if(our_chance)
|
||||
LAZYSET(loot, M, our_chance)
|
||||
return ..()
|
||||
|
||||
|
||||
// Tech storage circuit board spawners
|
||||
// For these, make sure that lootcount equals the number of list items
|
||||
|
||||
|
||||
@@ -686,7 +686,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
..()
|
||||
|
||||
/obj/item/proc/microwave_act(obj/machinery/microwave/M)
|
||||
if(M && M.dirty < 100)
|
||||
if(istype(M) && M.dirty < 100)
|
||||
M.dirty++
|
||||
|
||||
/obj/item/proc/on_mob_death(mob/living/L, gibbed)
|
||||
|
||||
@@ -707,9 +707,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
item_state = null
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/chem_volume = 100
|
||||
var/vapetime = 0 //this so it won't puff out clouds every tick
|
||||
var/screw = 0 // kinky
|
||||
var/super = 0 //for the fattest vapes dude.
|
||||
var/vapetime = FALSE //this so it won't puff out clouds every tick
|
||||
var/screw = FALSE // kinky
|
||||
var/super = FALSE //for the fattest vapes dude.
|
||||
|
||||
/obj/item/clothing/mask/vape/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is puffin hard on dat vape, [user.p_they()] trying to join the vape life on a whole notha plane!</span>")//it doesn't give you cancer, it is cancer
|
||||
@@ -718,7 +718,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
|
||||
/obj/item/clothing/mask/vape/Initialize(mapload, param_color)
|
||||
. = ..()
|
||||
DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
|
||||
create_reagents(chem_volume, NO_REACT) // so it doesn't react until you light it
|
||||
reagents.add_reagent("nicotine", 50)
|
||||
if(!icon_state)
|
||||
if(!param_color)
|
||||
@@ -727,45 +727,41 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
item_state = "[param_color]_vape"
|
||||
|
||||
/obj/item/clothing/mask/vape/attackby(obj/item/O, mob/user, params)
|
||||
if(O.is_drainable())
|
||||
if(reagents.total_volume < chem_volume)
|
||||
if(O.reagents.total_volume > 0)
|
||||
O.reagents.trans_to(src,25)
|
||||
to_chat(user, "<span class='notice'>You add the contents of [O] to [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[O] is empty!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] can't hold anymore reagents!</span>")
|
||||
|
||||
if(istype(O, /obj/item/screwdriver))
|
||||
if(O.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
if(!screw)
|
||||
screw = 1
|
||||
screw = TRUE
|
||||
to_chat(user, "<span class='notice'>You open the cap on [src].</span>")
|
||||
if(super)
|
||||
ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER)
|
||||
if(obj_flags & EMAGGED)
|
||||
add_overlay("vapeopen_high")
|
||||
else if(super)
|
||||
add_overlay("vapeopen_med")
|
||||
else
|
||||
add_overlay("vapeopen_low")
|
||||
else
|
||||
screw = 0
|
||||
screw = FALSE
|
||||
to_chat(user, "<span class='notice'>You close the cap on [src].</span>")
|
||||
DISABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER)
|
||||
cut_overlays()
|
||||
|
||||
if(istype(O, /obj/item/multitool))
|
||||
if(O.tool_behaviour == TOOL_MULTITOOL)
|
||||
if(screw && !(obj_flags & EMAGGED))//also kinky
|
||||
if(!super)
|
||||
cut_overlays()
|
||||
super = 1
|
||||
super = TRUE
|
||||
to_chat(user, "<span class='notice'>You increase the voltage of [src].</span>")
|
||||
add_overlay("vapeopen_med")
|
||||
else
|
||||
cut_overlays()
|
||||
super = 0
|
||||
super = FALSE
|
||||
to_chat(user, "<span class='notice'>You decrease the voltage of [src].</span>")
|
||||
add_overlay("vapeopen_low")
|
||||
|
||||
if(screw && (obj_flags & EMAGGED))
|
||||
to_chat(user, "<span class='notice'>[src] can't be modified!</span>")
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/clothing/mask/vape/emag_act(mob/user)// I WON'T REGRET WRITTING THIS, SURLY.
|
||||
. = ..()
|
||||
@@ -777,7 +773,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
return
|
||||
cut_overlays()
|
||||
obj_flags |= EMAGGED
|
||||
super = 0
|
||||
super = FALSE
|
||||
to_chat(user, "<span class='warning'>You maximize the voltage of [src].</span>")
|
||||
add_overlay("vapeopen_high")
|
||||
var/datum/effect_system/spark_spread/sp = new /datum/effect_system/spark_spread //for effect
|
||||
|
||||
@@ -123,6 +123,14 @@
|
||||
name = "Orion Trail (Computer Board)"
|
||||
build_path = /obj/machinery/computer/arcade/orion_trail
|
||||
|
||||
/obj/item/circuitboard/computer/arcade/minesweeper
|
||||
name = "Minesweeper (Computer Board)"
|
||||
build_path = /obj/machinery/computer/arcade/minesweeper
|
||||
|
||||
/obj/item/circuitboard/computer/arcade/amputation
|
||||
name = "Mediborg's Amputation Adventure (Computer Board)"
|
||||
build_path = /obj/machinery/computer/arcade/amputation
|
||||
|
||||
/obj/item/circuitboard/computer/turbine_control
|
||||
name = "Turbine control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/turbine_computer
|
||||
|
||||
@@ -10,6 +10,15 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
#define PDA_SCANNER_HALOGEN 4
|
||||
#define PDA_SCANNER_GAS 5
|
||||
#define PDA_SPAM_DELAY 2 MINUTES
|
||||
#define PDA_STANDARD_OVERLAYS list("pda-r", "blank", "id_overlay", "insert_overlay", "light_overlay", "pai_overlay")
|
||||
|
||||
//pda icon overlays list defines
|
||||
#define PDA_OVERLAY_ALERT 1
|
||||
#define PDA_OVERLAY_SCREEN 2
|
||||
#define PDA_OVERLAY_ID 3
|
||||
#define PDA_OVERLAY_ITEM 4
|
||||
#define PDA_OVERLAY_LIGHT 5
|
||||
#define PDA_OVERLAY_PAI 6
|
||||
|
||||
/obj/item/pda
|
||||
name = "\improper PDA"
|
||||
@@ -31,7 +40,8 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
var/default_cartridge = 0 // Access level defined by cartridge
|
||||
var/obj/item/cartridge/cartridge = null //current cartridge
|
||||
var/mode = 0 //Controls what menu the PDA will display. 0 is hub; the rest are either built in or based on cartridge.
|
||||
var/icon_alert = "pda-r" //Icon to be overlayed for message alerts. Taken from the pda icon file.
|
||||
var/list/overlays_icons = list('icons/obj/pda_alt.dmi' = list("pda-r", "screen_default", "id_overlay", "insert_overlay", "light_overlay", "pai_overlay"))
|
||||
var/current_overlays = PDA_STANDARD_OVERLAYS
|
||||
var/font_index = 0 //This int tells DM which font is currently selected and lets DM know when the last font has been selected so that it can cycle back to the first font when "toggle font" is pressed again.
|
||||
var/font_mode = "font-family:monospace;" //The currently selected font.
|
||||
var/background_color = "#808000" //The currently selected background color.
|
||||
@@ -78,7 +88,9 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
|
||||
var/list/contained_item = list(/obj/item/pen, /obj/item/toy/crayon, /obj/item/lipstick, /obj/item/flashlight/pen, /obj/item/clothing/mask/cigarette)
|
||||
var/obj/item/inserted_item //Used for pen, crayon, and lipstick insertion or removal. Same as above.
|
||||
var/overlays_x_offset = 0 //x offset to use for certain overlays
|
||||
var/list/overlays_offsets // offsets to use for certain overlays
|
||||
var/overlays_x_offset = 0
|
||||
var/overlays_y_offset = 0
|
||||
|
||||
var/underline_flag = TRUE //flag for underline
|
||||
|
||||
@@ -91,15 +103,13 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/pda/examine(mob/user)
|
||||
..()
|
||||
if(!id && !inserted_item)
|
||||
return
|
||||
|
||||
if(id)
|
||||
to_chat(user, "<span class='notice'>Alt-click to remove the id.</span>")
|
||||
|
||||
. = ..()
|
||||
var/dat = id ? "<span class='notice'>Alt-click to remove the id.</span>" : ""
|
||||
if(inserted_item && (!isturf(loc)))
|
||||
to_chat(user, "<span class='notice'>Ctrl-click to remove [inserted_item].</span>")
|
||||
dat += "\n<span class='notice'>Ctrl-click to remove [inserted_item].</span>"
|
||||
if(LAZYLEN(GLOB.pda_reskins))
|
||||
dat += "\n<span class='notice'>Ctrl-shift-click it to reskin it.</span>"
|
||||
to_chat(user, dat)
|
||||
|
||||
/obj/item/pda/Initialize()
|
||||
. = ..()
|
||||
@@ -115,28 +125,71 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
inserted_item = new /obj/item/pen(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/pda/CtrlShiftClick(mob/living/user)
|
||||
. = ..()
|
||||
if(GLOB.pda_reskins && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
|
||||
reskin_obj(user)
|
||||
|
||||
/obj/item/pda/reskin_obj(mob/M)
|
||||
if(!LAZYLEN(GLOB.pda_reskins))
|
||||
return
|
||||
var/dat = "<b>Reskin options for [name]:</b>"
|
||||
for(var/V in GLOB.pda_reskins)
|
||||
var/output = icon2html(GLOB.pda_reskins[V], M, icon_state)
|
||||
dat += "\n[V]: <span class='reallybig'>[output]</span>"
|
||||
to_chat(M, dat)
|
||||
|
||||
var/choice = input(M, "Choose the a reskin for [src]","Reskin Object") as null|anything in GLOB.pda_reskins
|
||||
var/new_icon = GLOB.pda_reskins[choice]
|
||||
if(QDELETED(src) || isnull(new_icon) || new_icon == icon || M.incapacitated() || !in_range(M,src))
|
||||
return
|
||||
icon = new_icon
|
||||
set_new_overlays()
|
||||
update_icon()
|
||||
to_chat(M, "[src] is now skinned as '[choice]'.")
|
||||
|
||||
/obj/item/pda/proc/set_new_overlays()
|
||||
if(!overlays_offsets || !(icon in overlays_offsets))
|
||||
overlays_x_offset = 0
|
||||
overlays_y_offset = 0
|
||||
else
|
||||
var/list/new_offsets = overlays_offsets[icon]
|
||||
if(new_offsets)
|
||||
overlays_x_offset = new_offsets[1]
|
||||
overlays_y_offset = new_offsets[2]
|
||||
if(!(icon in overlays_icons))
|
||||
current_overlays = PDA_STANDARD_OVERLAYS
|
||||
return
|
||||
current_overlays = overlays_icons[icon]
|
||||
|
||||
/obj/item/pda/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(!equipped)
|
||||
if(user.client)
|
||||
background_color = user.client.prefs.pda_color
|
||||
switch(user.client.prefs.pda_style)
|
||||
if(MONO)
|
||||
font_index = MODE_MONO
|
||||
font_mode = FONT_MONO
|
||||
if(SHARE)
|
||||
font_index = MODE_SHARE
|
||||
font_mode = FONT_SHARE
|
||||
if(ORBITRON)
|
||||
font_index = MODE_ORBITRON
|
||||
font_mode = FONT_ORBITRON
|
||||
if(VT)
|
||||
font_index = MODE_VT
|
||||
font_mode = FONT_VT
|
||||
else
|
||||
font_index = MODE_MONO
|
||||
font_mode = FONT_MONO
|
||||
equipped = TRUE
|
||||
if(equipped)
|
||||
return
|
||||
if(user.client)
|
||||
background_color = user.client.prefs.pda_color
|
||||
switch(user.client.prefs.pda_style)
|
||||
if(MONO)
|
||||
font_index = MODE_MONO
|
||||
font_mode = FONT_MONO
|
||||
if(SHARE)
|
||||
font_index = MODE_SHARE
|
||||
font_mode = FONT_SHARE
|
||||
if(ORBITRON)
|
||||
font_index = MODE_ORBITRON
|
||||
font_mode = FONT_ORBITRON
|
||||
if(VT)
|
||||
font_index = MODE_VT
|
||||
font_mode = FONT_VT
|
||||
else
|
||||
font_index = MODE_MONO
|
||||
font_mode = FONT_MONO
|
||||
var/pref_skin = GLOB.pda_reskins[user.client.prefs.pda_skin]
|
||||
if(icon != pref_skin)
|
||||
icon = pref_skin
|
||||
set_new_overlays()
|
||||
update_icon()
|
||||
equipped = TRUE
|
||||
|
||||
/obj/item/pda/proc/update_label()
|
||||
name = "PDA-[owner] ([ownjob])" //Name generalisation
|
||||
@@ -150,33 +203,34 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
/obj/item/pda/GetID()
|
||||
return id
|
||||
|
||||
/obj/item/pda/update_icon()
|
||||
/obj/item/pda/update_icon(alert = FALSE)
|
||||
cut_overlays()
|
||||
add_overlay(alert ? current_overlays[PDA_OVERLAY_ALERT] : current_overlays[PDA_OVERLAY_SCREEN])
|
||||
var/mutable_appearance/overlay = new()
|
||||
overlay.pixel_x = overlays_x_offset
|
||||
if(id)
|
||||
overlay.icon_state = "id_overlay"
|
||||
overlay.icon_state = current_overlays[PDA_OVERLAY_ID]
|
||||
add_overlay(new /mutable_appearance(overlay))
|
||||
if(inserted_item)
|
||||
overlay.icon_state = "insert_overlay"
|
||||
overlay.icon_state = current_overlays[PDA_OVERLAY_ITEM]
|
||||
add_overlay(new /mutable_appearance(overlay))
|
||||
if(fon)
|
||||
overlay.icon_state = "light_overlay"
|
||||
overlay.icon_state = current_overlays[PDA_OVERLAY_LIGHT]
|
||||
add_overlay(new /mutable_appearance(overlay))
|
||||
if(pai)
|
||||
if(pai.pai)
|
||||
overlay.icon_state = "pai_overlay"
|
||||
add_overlay(new /mutable_appearance(overlay))
|
||||
else
|
||||
overlay.icon_state = "pai_off_overlay"
|
||||
add_overlay(new /mutable_appearance(overlay))
|
||||
overlay.icon_state = "[current_overlays[PDA_OVERLAY_PAI]][pai.pai ? "" : "_off"]"
|
||||
add_overlay(new /mutable_appearance(overlay))
|
||||
|
||||
/obj/item/pda/MouseDrop(obj/over_object, src_location, over_location)
|
||||
/obj/item/pda/MouseDrop(mob/over, src_location, over_location)
|
||||
var/mob/M = usr
|
||||
if((!istype(over_object, /obj/screen)) && usr.canUseTopic(src))
|
||||
if((M == over) && usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return attack_self(M)
|
||||
return ..()
|
||||
|
||||
/obj/item/pda/attack_self_tk(mob/user)
|
||||
to_chat(user, "<span class='warning'>The PDA's capacitive touch screen doesn't seem to respond!</span>")
|
||||
return
|
||||
|
||||
/obj/item/pda/interact(mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
@@ -382,7 +436,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
var/mob/living/U = usr
|
||||
//Looking for master was kind of pointless since PDAs don't appear to have one.
|
||||
|
||||
if(usr.canUseTopic(src) && !href_list["close"])
|
||||
if(usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) && !href_list["close"])
|
||||
add_fingerprint(U)
|
||||
U.set_machine(src)
|
||||
|
||||
@@ -636,7 +690,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
|
||||
/obj/item/pda/proc/remove_id()
|
||||
|
||||
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE))
|
||||
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
|
||||
if (id)
|
||||
@@ -736,8 +790,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
|
||||
to_chat(L, "[icon2html(src)] <b>Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], </b>[signal.format_message()] (<a href='byond://?src=[REF(src)];choice=Message;skiprefresh=1;target=[REF(signal.source)]'>Reply</a>)")
|
||||
|
||||
update_icon()
|
||||
add_overlay(icon_alert)
|
||||
update_icon(TRUE)
|
||||
|
||||
/obj/item/pda/proc/send_to_all(mob/living/U)
|
||||
if (last_everyone && world.time < last_everyone + PDA_SPAM_DELAY)
|
||||
@@ -802,7 +855,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
|
||||
/obj/item/pda/proc/remove_pen()
|
||||
|
||||
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE))
|
||||
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
|
||||
if(inserted_item)
|
||||
@@ -1076,4 +1129,11 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
#undef PDA_SCANNER_HALOGEN
|
||||
#undef PDA_SCANNER_GAS
|
||||
#undef PDA_SPAM_DELAY
|
||||
#undef PDA_STANDARD_OVERLAYS
|
||||
|
||||
#undef PDA_OVERLAY_ALERT
|
||||
#undef PDA_OVERLAY_SCREEN
|
||||
#undef PDA_OVERLAY_ID
|
||||
#undef PDA_OVERLAY_ITEM
|
||||
#undef PDA_OVERLAY_LIGHT
|
||||
#undef PDA_OVERLAY_PAI
|
||||
@@ -124,6 +124,16 @@
|
||||
icon_state = "pda-captain"
|
||||
detonatable = FALSE
|
||||
|
||||
/obj/item/pda/lieutenant
|
||||
name = "lieutenant PDA"
|
||||
default_cartridge = /obj/item/cartridge/captain
|
||||
inserted_item = /obj/item/pen/fountain/captain
|
||||
icon_state = "pda-lieutenant"
|
||||
ttone = "bwoink"
|
||||
detonatable = FALSE
|
||||
hidden = TRUE
|
||||
note = "Congratulations, you have chosen the Thinktronic 5230-2 Personal Data Assistant Prestige Edition! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft."
|
||||
|
||||
/obj/item/pda/cargo
|
||||
name = "cargo technician PDA"
|
||||
default_cartridge = /obj/item/cartridge/quartermaster
|
||||
@@ -171,25 +181,29 @@
|
||||
/obj/item/pda/curator
|
||||
name = "curator PDA"
|
||||
icon_state = "pda-library"
|
||||
icon_alert = "pda-r-library"
|
||||
overlays_icons = list('icons/obj/pda.dmi' = list("pda-r-library","blank","id_overlay","insert_overlay", "light_overlay", "pai_overlay"),
|
||||
'icons/obj/pda_alt.dmi' = list("pda-r","screen_default","id_overlay","insert_overlay", "light_overlay", "pai_overlay"))
|
||||
current_overlays = list("pda-r-library","blank","id_overlay","insert_overlay", "light_overlay", "pai_overlay")
|
||||
default_cartridge = /obj/item/cartridge/curator
|
||||
inserted_item = /obj/item/pen/fountain
|
||||
desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a WGW-11 series e-reader."
|
||||
note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant!"
|
||||
note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft."
|
||||
silent = TRUE //Quiet in the library!
|
||||
overlays_offsets = list('icons/obj/pda.dmi' = list(-3,0))
|
||||
overlays_x_offset = -3
|
||||
|
||||
/obj/item/pda/clear
|
||||
name = "clear PDA"
|
||||
icon_state = "pda-clear"
|
||||
desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a special edition with a transparent case."
|
||||
note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition!"
|
||||
note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft."
|
||||
|
||||
/obj/item/pda/neko
|
||||
name = "neko PDA"
|
||||
icon_state = "pda-neko"
|
||||
desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a special edition a feline fine case."
|
||||
note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Mew Turbo Limited Edition NYA~!"
|
||||
overlays_icons = list('icons/obj/pda_alt.dmi' = list("pda-r", "screen_neko", "id_overlay", "insert_overlay", "light_overlay", "pai_overlay"))
|
||||
desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a special feline edition."
|
||||
note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Mew Turbo Limited Edition NYA~! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft."
|
||||
|
||||
/obj/item/pda/cook
|
||||
name = "cook PDA"
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
actions_types = list(/datum/action/item_action/toggle_light)
|
||||
var/on = FALSE
|
||||
var/brightness_on = 4 //range of light when on
|
||||
var/flashlight_power = 1 //strength of the light when on
|
||||
var/flashlight_power = 0.8 //strength of the light when on
|
||||
light_color = "#FFCC66"
|
||||
|
||||
/obj/item/flashlight/Initialize()
|
||||
. = ..()
|
||||
@@ -63,7 +64,7 @@
|
||||
to_chat(user, "<span class='warning'>[M] doesn't have a head!</span>")
|
||||
return
|
||||
|
||||
if(flashlight_power < 1)
|
||||
if(flashlight_power < 0.3)
|
||||
to_chat(user, "<span class='warning'>\The [src] isn't bright enough to see anything!</span> ")
|
||||
return
|
||||
|
||||
@@ -168,6 +169,8 @@
|
||||
item_state = ""
|
||||
flags_1 = CONDUCT_1
|
||||
brightness_on = 2
|
||||
light_color = "#FFDDCC"
|
||||
flashlight_power = 0.3
|
||||
var/holo_cooldown = 0
|
||||
|
||||
/obj/item/flashlight/pen/afterattack(atom/target, mob/user, proximity_flag)
|
||||
@@ -204,6 +207,8 @@
|
||||
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
|
||||
force = 9 // Not as good as a stun baton.
|
||||
brightness_on = 5 // A little better than the standard flashlight.
|
||||
light_color = "#CDDDFF"
|
||||
flashlight_power = 0.9
|
||||
hitsound = 'sound/weapons/genhit1.ogg'
|
||||
|
||||
// the desk lamps are a bit special
|
||||
@@ -216,6 +221,7 @@
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
force = 10
|
||||
brightness_on = 5
|
||||
light_color = "#FFDDBB"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
flags_1 = CONDUCT_1
|
||||
materials = list()
|
||||
@@ -252,6 +258,7 @@
|
||||
desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
brightness_on = 7 // Pretty bright.
|
||||
light_color = "#FA421A"
|
||||
icon_state = "flare"
|
||||
item_state = "flare"
|
||||
actions_types = list()
|
||||
@@ -325,6 +332,7 @@
|
||||
desc = "A torch fashioned from some leaves and a log."
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
brightness_on = 4
|
||||
light_color = "#FAA44B"
|
||||
icon_state = "torch"
|
||||
item_state = "torch"
|
||||
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
||||
@@ -341,6 +349,8 @@
|
||||
righthand_file = 'icons/mob/inhands/equipment/mining_righthand.dmi'
|
||||
desc = "A mining lantern."
|
||||
brightness_on = 6 // luminosity when on
|
||||
light_color = "#FFAA44"
|
||||
flashlight_power = 0.75
|
||||
|
||||
|
||||
/obj/item/flashlight/slime
|
||||
@@ -354,6 +364,8 @@
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
materials = list()
|
||||
brightness_on = 6 //luminosity when on
|
||||
light_color = "#FFEEAA"
|
||||
flashlight_power = 0.6
|
||||
|
||||
/obj/item/flashlight/emp
|
||||
var/emp_max_charges = 4
|
||||
@@ -517,6 +529,7 @@
|
||||
icon_state = null
|
||||
light_color = null
|
||||
brightness_on = 0
|
||||
flashlight_power = 1
|
||||
light_range = 0
|
||||
light_power = 10
|
||||
alpha = 0
|
||||
@@ -538,7 +551,6 @@
|
||||
name = "eyelight"
|
||||
desc = "This shouldn't exist outside of someone's head, how are you seeing this?"
|
||||
brightness_on = 15
|
||||
flashlight_power = 1
|
||||
flags_1 = CONDUCT_1
|
||||
item_flags = DROPDEL
|
||||
actions_types = list()
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
item_state = "radio"
|
||||
|
||||
/obj/item/holybeacon/attack_self(mob/user)
|
||||
if(user.mind && (user.mind.isholy) && !SSreligion.holy_armor_type)
|
||||
if(user.mind && (user.mind.isholy) && !GLOB.holy_armor_type)
|
||||
beacon_armor(user)
|
||||
else
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 40, 1)
|
||||
@@ -71,13 +71,13 @@
|
||||
display_names += list(initial(A.name) = A)
|
||||
|
||||
var/choice = input(M,"What holy armor kit would you like to order?","Holy Armor Theme") as null|anything in display_names
|
||||
if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || SSreligion.holy_armor_type)
|
||||
if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || GLOB.holy_armor_type)
|
||||
return
|
||||
|
||||
var/index = display_names.Find(choice)
|
||||
var/A = holy_armor_list[index]
|
||||
|
||||
SSreligion.holy_armor_type = A
|
||||
GLOB.holy_armor_type = A
|
||||
var/holy_armor_box = new A
|
||||
|
||||
SSblackbox.record_feedback("tally", "chaplain_armor", 1, "[choice]")
|
||||
@@ -245,7 +245,7 @@
|
||||
reskin_holy_weapon(user)
|
||||
|
||||
/obj/item/nullrod/proc/reskin_holy_weapon(mob/M)
|
||||
if(SSreligion.holy_weapon_type)
|
||||
if(GLOB.holy_weapon_type)
|
||||
return
|
||||
var/obj/item/nullrod/holy_weapon
|
||||
var/list/holy_weapons_list = typesof(/obj/item/nullrod) + list(
|
||||
@@ -264,7 +264,7 @@
|
||||
var/A = display_names[choice] // This needs to be on a separate var as list member access is not allowed for new
|
||||
holy_weapon = new A
|
||||
|
||||
SSreligion.holy_weapon_type = holy_weapon.type
|
||||
GLOB.holy_weapon_type = holy_weapon.type
|
||||
|
||||
SSblackbox.record_feedback("tally", "chaplain_weapon", 1, "[choice]")
|
||||
|
||||
|
||||
@@ -613,6 +613,20 @@
|
||||
icon_state = "plushie_awake"
|
||||
item_state = "plushie_awake"
|
||||
|
||||
/obj/item/toy/plush/awakenedplushie/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/edit_complainer)
|
||||
|
||||
|
||||
/obj/item/toy/plush/beeplushie
|
||||
name = "bee plushie"
|
||||
desc = "A cute toy that resembles an even cuter bee."
|
||||
icon_state = "plushie_h"
|
||||
item_state = "plushie_h"
|
||||
attack_verb = list("stung")
|
||||
gender = FEMALE
|
||||
squeak_override = list('modular_citadel/sound/voice/scream_moth.ogg' = 1)
|
||||
|
||||
/obj/item/toy/plush/mothplushie
|
||||
name = "insect plushie"
|
||||
desc = "An adorable stuffed toy that resembles some kind of insect"
|
||||
@@ -904,7 +918,3 @@
|
||||
item_state = "fermis"
|
||||
attack_verb = list("cuddled", "petpatted", "wigglepurred")
|
||||
squeak_override = list('modular_citadel/sound/voice/merowr.ogg' = 1)
|
||||
|
||||
/obj/item/toy/plush/awakenedplushie/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/edit_complainer)
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
name = "tower shield"
|
||||
desc = "A massive shield that can block a lot of attacks, can take a lot of abuse before braking."
|
||||
armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user
|
||||
icon_state = "metal"
|
||||
item_state = "metal"
|
||||
block_chance = 75 //1/4 shots will hit*
|
||||
force = 10
|
||||
slowdown = 2
|
||||
|
||||
@@ -396,7 +396,7 @@
|
||||
//TODO bloody overlay
|
||||
|
||||
/obj/item/stack/microwave_act(obj/machinery/microwave/M)
|
||||
if(M && M.dirty < 100)
|
||||
if(istype(M) && M.dirty < 100)
|
||||
M.dirty += amount
|
||||
|
||||
/*
|
||||
|
||||
@@ -589,3 +589,16 @@
|
||||
new /obj/item/clothing/mask/gas/clown_hat(src)
|
||||
new /obj/item/bikehorn(src)
|
||||
new /obj/item/implanter/sad_trombone(src)
|
||||
|
||||
obj/item/storage/backpack/duffelbag/syndie/shredderbundle
|
||||
desc = "A large duffel bag containing two CX Shredders, some magazines, an elite hardsuit, and a chest rig."
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/syndie/shredderbundle/PopulateContents()
|
||||
new /obj/item/ammo_box/magazine/flechette/shredder(src)
|
||||
new /obj/item/ammo_box/magazine/flechette/shredder(src)
|
||||
new /obj/item/ammo_box/magazine/flechette/shredder(src)
|
||||
new /obj/item/ammo_box/magazine/flechette/shredder(src)
|
||||
new /obj/item/gun/ballistic/automatic/flechette/shredder(src)
|
||||
new /obj/item/gun/ballistic/automatic/flechette/shredder(src)
|
||||
new /obj/item/storage/belt/military(src)
|
||||
new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src)
|
||||
|
||||
@@ -541,6 +541,25 @@
|
||||
/obj/item/ammo_casing/shotgun
|
||||
))
|
||||
|
||||
/obj/item/storage/belt/medolier
|
||||
name = "medolier"
|
||||
desc = "A medical bandolier for holding smartdarts."
|
||||
icon_state = "medolier"
|
||||
item_state = "medolier"
|
||||
|
||||
/obj/item/storage/belt/medolier/ComponentInitialize()
|
||||
. = ..()
|
||||
GET_COMPONENT(STR, /datum/component/storage)
|
||||
STR.max_items = 15
|
||||
STR.display_numerical_stacking = FALSE
|
||||
STR.can_hold = typecacheof(list(
|
||||
/obj/item/reagent_containers/syringe/dart
|
||||
))
|
||||
|
||||
/obj/item/storage/belt/medolier/full/PopulateContents()
|
||||
for(var/i in 1 to 16)
|
||||
new /obj/item/reagent_containers/syringe/dart/(src)
|
||||
|
||||
/obj/item/storage/belt/holster
|
||||
name = "shoulder holster"
|
||||
desc = "A holster to carry a handgun and ammo. WARNING: Badasses only."
|
||||
@@ -557,6 +576,8 @@
|
||||
/obj/item/gun/ballistic/automatic/pistol,
|
||||
/obj/item/gun/ballistic/revolver,
|
||||
/obj/item/ammo_box,
|
||||
/obj/item/toy/gun,
|
||||
/obj/item/gun/energy/e_gun/mini
|
||||
))
|
||||
|
||||
/obj/item/storage/belt/holster/full/PopulateContents()
|
||||
|
||||
@@ -51,7 +51,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
if(!istype(H))
|
||||
return
|
||||
// If H is the Chaplain, we can set the icon_state of the bible (but only once!)
|
||||
if(!SSreligion.bible_icon_state && H.job == "Chaplain")
|
||||
if(!GLOB.bible_icon_state && H.job == "Chaplain")
|
||||
var/dat = "<html><head><title>Pick Bible Style</title></head><body><center><h2>Pick a bible style</h2></center><table>"
|
||||
for(var/i in 1 to GLOB.biblestates.len)
|
||||
var/icon/bibleicon = icon('icons/obj/storage.dmi', GLOB.biblestates[i])
|
||||
@@ -64,7 +64,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
/obj/item/storage/book/bible/Topic(href, href_list)
|
||||
if(!usr.canUseTopic(src))
|
||||
return
|
||||
if(href_list["seticon"] && SSreligion && !SSreligion.bible_icon_state)
|
||||
if(href_list["seticon"] && GLOB && !GLOB.bible_icon_state)
|
||||
var/iconi = text2num(href_list["seticon"])
|
||||
var/biblename = GLOB.biblenames[iconi]
|
||||
var/obj/item/storage/book/bible/B = locate(href_list["src"])
|
||||
@@ -76,8 +76,8 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
H.dna.add_mutation(CLOWNMUT)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(H), SLOT_WEAR_MASK)
|
||||
|
||||
SSreligion.bible_icon_state = B.icon_state
|
||||
SSreligion.bible_item_state = B.item_state
|
||||
GLOB.bible_icon_state = B.icon_state
|
||||
GLOB.bible_item_state = B.item_state
|
||||
|
||||
SSblackbox.record_feedback("text", "religion_book", 1, "[biblename]")
|
||||
usr << browse(null, "window=editicon")
|
||||
@@ -89,7 +89,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
to_chat(user, "<span class='warning'>[src.deity_name] refuses to heal this metallic taint!</span>")
|
||||
return 0
|
||||
|
||||
var/heal_amt = 10
|
||||
var/heal_amt = 5
|
||||
var/list/hurt_limbs = H.get_damaged_bodyparts(1, 1)
|
||||
|
||||
if(hurt_limbs.len)
|
||||
@@ -138,8 +138,8 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
smack = 0
|
||||
else if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
if(!istype(C.head, /obj/item/clothing/head/helmet))
|
||||
C.adjustBrainLoss(5, 60)
|
||||
if(!istype(C.head, /obj/item/clothing/head))
|
||||
C.adjustBrainLoss(10, 80)
|
||||
to_chat(C, "<span class='danger'>You feel dumber.</span>")
|
||||
|
||||
if(smack)
|
||||
|
||||
@@ -1126,3 +1126,73 @@
|
||||
/obj/item/storage/box/pink
|
||||
icon_state = "box_pink"
|
||||
illustration = null
|
||||
|
||||
/obj/item/storage/box/mre //base MRE type.
|
||||
name = "Nanotrasen MRE Ration Kit Menu 0"
|
||||
desc = "A package containing food suspended in an outdated bluespace pocket which lasts for centuries. If you're lucky you may even be able to enjoy the meal without getting food poisoning."
|
||||
icon_state = "mre"
|
||||
var/can_expire = TRUE
|
||||
var/spawner_chance = 2
|
||||
var/expiration_date
|
||||
var/expiration_date_min = 2300
|
||||
var/expiration_date_max = 2700
|
||||
|
||||
/obj/item/storage/box/mre/Initialize()
|
||||
. = ..()
|
||||
if(can_expire)
|
||||
expiration_date = rand(expiration_date_min, expiration_date_max)
|
||||
desc += "\n<span_clas='notice'>An expiry date is listed on it. It reads: [expiration_date]</span>"
|
||||
var/spess_current_year = GLOB.year_integer + 540
|
||||
if(expiration_date < spess_current_year)
|
||||
var/gross_risk = min(round(spess_current_year - expiration_date * 0.1), 1)
|
||||
var/toxic_risk = min(round(spess_current_year - expiration_date * 0.01), 1)
|
||||
for(var/obj/item/reagent_containers/food/snacks/S in contents)
|
||||
if(prob(gross_risk))
|
||||
ENABLE_BITFIELD(S.foodtype, GROSS)
|
||||
if(prob(toxic_risk))
|
||||
ENABLE_BITFIELD(S.foodtype, TOXIC)
|
||||
|
||||
/obj/item/storage/box/mre/menu1
|
||||
name = "\improper Nanotrasen MRE Ration Kit Menu 1"
|
||||
|
||||
/obj/item/storage/box/mre/menu1/safe
|
||||
desc = "A package containing food suspended in a bluespace pocket capable of lasting till the end of time."
|
||||
spawner_chance = 0
|
||||
can_expire = FALSE
|
||||
|
||||
/obj/item/storage/box/mre/menu1/PopulateContents()
|
||||
new /obj/item/reagent_containers/food/snacks/breadslice/plain(src)
|
||||
new /obj/item/reagent_containers/food/snacks/breadslice/creamcheese(src)
|
||||
new /obj/item/reagent_containers/food/condiment/pack/ketchup(src)
|
||||
new /obj/item/reagent_containers/food/snacks/chocolatebar(src)
|
||||
new /obj/item/tank/internals/emergency_oxygen(src)
|
||||
|
||||
/obj/item/storage/box/mre/menu2
|
||||
name = "\improper Nanotrasen MRE Ration Kit Menu 2"
|
||||
|
||||
/obj/item/storage/box/mre/menu2/safe
|
||||
spawner_chance = 0
|
||||
desc = "A package containing food suspended in a bluespace pocket capable of lasting till the end of time."
|
||||
can_expire = FALSE
|
||||
|
||||
/obj/item/storage/box/mre/menu2/PopulateContents()
|
||||
new /obj/item/reagent_containers/food/snacks/omelette(src)
|
||||
new /obj/item/reagent_containers/food/snacks/meat/cutlet/plain(src)
|
||||
new /obj/item/reagent_containers/food/snacks/fries(src)
|
||||
new /obj/item/reagent_containers/food/snacks/chocolatebar(src)
|
||||
new /obj/item/tank/internals/emergency_oxygen(src)
|
||||
|
||||
/obj/item/storage/box/mre/menu3
|
||||
name = "\improper Nanotrasen MRE Ration Kit Menu 3"
|
||||
desc = "The holy grail of MREs. This item contains the fabled MRE pizza and a sample of coffee instant type 2. Any NT employee lucky enough to get their hands on one of these is truly blessed."
|
||||
icon_state = "menu3"
|
||||
can_expire = FALSE //always fresh, never expired.
|
||||
spawner_chance = 1
|
||||
|
||||
/obj/item/storage/box/mre/menu3/PopulateContents()
|
||||
new /obj/item/reagent_containers/food/snacks/pizzaslice/pepperoni(src)
|
||||
new /obj/item/reagent_containers/food/snacks/breadslice/plain(src)
|
||||
new /obj/item/reagent_containers/food/snacks/cheesewedge(src)
|
||||
new /obj/item/reagent_containers/food/snacks/grown/chili(src)
|
||||
new /obj/item/reagent_containers/food/drinks/coffee/type2(src)
|
||||
new /obj/item/tank/internals/emergency_oxygen(src)
|
||||
|
||||
@@ -80,6 +80,21 @@
|
||||
new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src)
|
||||
new /obj/item/suppressor/specialoffer(src)
|
||||
|
||||
|
||||
/obj/item/storage/briefcase/modularbundle
|
||||
desc = "It's label reads genuine hardened Captain leather, but suspiciously has no other tags or branding."
|
||||
force = 10
|
||||
|
||||
/obj/item/storage/briefcase/modularbundle/PopulateContents()
|
||||
new /obj/item/gun/ballistic/automatic/pistol/modular(src)
|
||||
new /obj/item/suppressor(src)
|
||||
new /obj/item/ammo_box/magazine/m10mm(src)
|
||||
new /obj/item/ammo_box/magazine/m10mm/soporific(src)
|
||||
new /obj/item/ammo_box/c10mm/soporific(src)
|
||||
new /obj/item/clothing/under/lawyer/blacksuit(src)
|
||||
new /obj/item/clothing/accessory/waistcoat(src)
|
||||
new /obj/item/clothing/suit/toggle/lawyer/black/syndie(src)
|
||||
|
||||
/obj/item/storage/briefcase/medical
|
||||
name = "medical briefcase"
|
||||
icon_state = "medbriefcase"
|
||||
@@ -89,3 +104,4 @@
|
||||
new /obj/item/clothing/neck/stethoscope(src)
|
||||
new /obj/item/healthanalyzer(src)
|
||||
..() //In case of paperwork
|
||||
|
||||
|
||||
@@ -183,9 +183,9 @@
|
||||
slab_type = /obj/item/clockwork/slab/debug
|
||||
fabricator_type = /obj/item/clockwork/replica_fabricator/scarab/debug
|
||||
|
||||
/obj/item/storage/toolbox/durasteel
|
||||
name = "durasteel toolbox"
|
||||
desc = "A toolbox made out of durasteel. Probably packs a massive punch."
|
||||
/obj/item/storage/toolbox/plastitanium
|
||||
name = "plastitanium toolbox"
|
||||
desc = "A toolbox made out of plastitanium. Probably packs a massive punch."
|
||||
total_mass = 5
|
||||
icon_state = "blue"
|
||||
item_state = "toolbox_blue"
|
||||
|
||||
@@ -160,6 +160,11 @@
|
||||
distribute_pressure = 0
|
||||
gas_type = /datum/gas/carbon_dioxide
|
||||
|
||||
/obj/item/tank/jetpack/carbondioxide/eva
|
||||
name = "surplus jetpack (carbon dioxide)"
|
||||
desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals. Rated for less than stellar EVA speeds!"
|
||||
full_speed = FALSE
|
||||
|
||||
/obj/item/tank/jetpack/suit
|
||||
name = "hardsuit jetpack upgrade"
|
||||
desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment."
|
||||
|
||||
@@ -636,10 +636,13 @@
|
||||
var/obj/machinery/computer/holodeck/holo = null // Holodeck cards should not be infinite
|
||||
var/list/cards = list()
|
||||
|
||||
/obj/item/toy/cards/deck/New()
|
||||
..()
|
||||
/obj/item/toy/cards/deck/Initialize()
|
||||
. = ..()
|
||||
populate_deck()
|
||||
|
||||
/obj/item/toy/cards/deck/proc/populate_deck()
|
||||
icon_state = "deck_[deckstyle]_full"
|
||||
for(var/i = 2; i <= 10; i++)
|
||||
for(var/i in 2 to 10)
|
||||
cards += "[i] of Hearts"
|
||||
cards += "[i] of Spades"
|
||||
cards += "[i] of Clubs"
|
||||
@@ -664,6 +667,9 @@
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
//ATTACK HAND NOT CALLING PARENT
|
||||
/obj/item/toy/cards/deck/attack_hand(mob/user)
|
||||
draw_card(user)
|
||||
|
||||
/obj/item/toy/cards/deck/proc/draw_card(mob/user)
|
||||
if(user.lying)
|
||||
return
|
||||
var/choice = null
|
||||
@@ -778,7 +784,7 @@
|
||||
/obj/item/toy/cards/cardhand/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
if(usr.stat || !ishuman(usr) || !usr.canmove)
|
||||
if(usr.stat || !ishuman(usr))
|
||||
return
|
||||
var/mob/living/carbon/human/cardUser = usr
|
||||
var/O = src
|
||||
@@ -941,7 +947,6 @@
|
||||
newobj.card_attack_verb = sourceobj.card_attack_verb
|
||||
newobj.attack_verb = newobj.card_attack_verb
|
||||
|
||||
|
||||
/*
|
||||
|| Syndicate playing cards, for pretending you're Gambit and playing poker for the nuke disk. ||
|
||||
*/
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
var/acid_level = 0 //how much acid is on that obj
|
||||
|
||||
var/persistence_replacement //have something WAY too amazing to live to the next round? Set a new path here. Overuse of this var will make me upset.
|
||||
var/current_skin //Has the item been reskinned?
|
||||
var/current_skin //the item reskin
|
||||
var/list/unique_reskin //List of options to reskin.
|
||||
var/always_reskinnable = FALSE
|
||||
|
||||
// Access levels, used in modules\jobs\access.dm
|
||||
var/list/req_access
|
||||
@@ -228,26 +229,26 @@
|
||||
..()
|
||||
if(obj_flags & UNIQUE_RENAME)
|
||||
to_chat(user, "<span class='notice'>Use a pen on it to rename it or change its description.</span>")
|
||||
if(unique_reskin && !current_skin)
|
||||
if(unique_reskin && (!current_skin || always_reskinnable))
|
||||
to_chat(user, "<span class='notice'>Alt-click it to reskin it.</span>")
|
||||
|
||||
/obj/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(unique_reskin && !current_skin && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
|
||||
if(unique_reskin && (!current_skin || always_reskinnable) && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
|
||||
reskin_obj(user)
|
||||
|
||||
/obj/proc/reskin_obj(mob/M)
|
||||
if(!LAZYLEN(unique_reskin))
|
||||
return
|
||||
to_chat(M, "<b>Reskin options for [name]:</b>")
|
||||
var/dat = "<b>Reskin options for [name]:</b>\n"
|
||||
for(var/V in unique_reskin)
|
||||
var/output = icon2html(src, M, unique_reskin[V])
|
||||
to_chat(M, "[V]: <span class='reallybig'>[output]</span>")
|
||||
dat += "[V]: <span class='reallybig'>[output]</span>\n"
|
||||
to_chat(M, dat)
|
||||
|
||||
var/choice = input(M,"Warning, you can only reskin [src] once!","Reskin Object") as null|anything in unique_reskin
|
||||
if(!QDELETED(src) && choice && !current_skin && !M.incapacitated() && in_range(M,src))
|
||||
if(!unique_reskin[choice])
|
||||
return
|
||||
current_skin = choice
|
||||
icon_state = unique_reskin[choice]
|
||||
to_chat(M, "[src] is now skinned as '[choice].'")
|
||||
var/choice = input(M, always_reskinnable ? "Choose the a reskin for [src]" : "Warning, you can only reskin [src] once!","Reskin Object") as null|anything in unique_reskin
|
||||
if(QDELETED(src) || !choice || (current_skin && !always_reskinnable) || M.incapacitated() || !in_range(M,src) || !unique_reskin[choice] || unique_reskin[choice] == current_skin)
|
||||
return
|
||||
current_skin = choice
|
||||
icon_state = unique_reskin[choice]
|
||||
to_chat(M, "[src] is now skinned as '[choice]'.")
|
||||
|
||||
@@ -24,15 +24,13 @@
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
|
||||
var/userloc = H.loc
|
||||
|
||||
//see code/modules/mob/dead/new_player/preferences.dm at approx line 545 for comments!
|
||||
//this is largely copypasted from there.
|
||||
|
||||
//handle facial hair (if necessary)
|
||||
if(H.gender == MALE)
|
||||
var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in GLOB.facial_hair_styles_list
|
||||
if(userloc != H.loc)
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return //no tele-grooming
|
||||
if(new_style)
|
||||
H.facial_hair_style = new_style
|
||||
@@ -41,7 +39,7 @@
|
||||
|
||||
//handle normal hair
|
||||
var/new_style = input(user, "Select a hair style", "Grooming") as null|anything in GLOB.hair_styles_list
|
||||
if(userloc != H.loc)
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return //no tele-grooming
|
||||
if(new_style)
|
||||
H.hair_style = new_style
|
||||
@@ -90,9 +88,9 @@
|
||||
/obj/structure/mirror/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
|
||||
playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
|
||||
if(BURN)
|
||||
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
|
||||
playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
|
||||
|
||||
|
||||
/obj/structure/mirror/magic
|
||||
@@ -131,7 +129,7 @@
|
||||
|
||||
var/choice = input(user, "Something to change?", "Magical Grooming") as null|anything in list("name", "race", "gender", "hair", "eyes")
|
||||
|
||||
if(!Adjacent(user))
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
|
||||
switch(choice)
|
||||
@@ -140,7 +138,7 @@
|
||||
|
||||
if(!newname)
|
||||
return
|
||||
if(!Adjacent(user))
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
H.real_name = newname
|
||||
H.name = newname
|
||||
@@ -156,7 +154,7 @@
|
||||
|
||||
if(!newrace)
|
||||
return
|
||||
if(!Adjacent(user))
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
H.set_species(newrace, icon_update=0)
|
||||
|
||||
@@ -186,7 +184,7 @@
|
||||
if("gender")
|
||||
if(!(H.gender in list("male", "female"))) //blame the patriarchy
|
||||
return
|
||||
if(!Adjacent(user))
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
if(H.gender == "male")
|
||||
if(alert(H, "Become a Witch?", "Confirmation", "Yes", "No") == "Yes")
|
||||
@@ -207,7 +205,7 @@
|
||||
|
||||
if("hair")
|
||||
var/hairchoice = alert(H, "Hair style or hair color?", "Change Hair", "Style", "Color")
|
||||
if(!Adjacent(user))
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
if(hairchoice == "Style") //So you just want to use a mirror then?
|
||||
..()
|
||||
@@ -225,7 +223,7 @@
|
||||
|
||||
if(BODY_ZONE_PRECISE_EYES)
|
||||
var/new_eye_color = input(H, "Choose your eye color", "Eye Color","#"+H.eye_color) as color|null
|
||||
if(!Adjacent(user))
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
if(new_eye_color)
|
||||
H.eye_color = sanitize_hexcolor(new_eye_color)
|
||||
|
||||
@@ -29,69 +29,62 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
/client/proc/callproc()
|
||||
set category = "Debug"
|
||||
set name = "Advanced ProcCall"
|
||||
set waitfor = 0
|
||||
set waitfor = FALSE
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/datum/target = null
|
||||
var/targetselected = 0
|
||||
var/targetselected = FALSE
|
||||
var/returnval = null
|
||||
|
||||
switch(alert("Proc owned by something?",,"Yes","No"))
|
||||
if("Yes")
|
||||
targetselected = 1
|
||||
var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT))
|
||||
if (!value["class"] || !value["value"])
|
||||
return
|
||||
target = value["value"]
|
||||
if("No")
|
||||
target = null
|
||||
targetselected = 0
|
||||
|
||||
var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
|
||||
if(!procname)
|
||||
return
|
||||
|
||||
//hascall() doesn't support proc paths (eg: /proc/gib(), it only supports "gib")
|
||||
var/testname = procname
|
||||
if(targetselected)
|
||||
//Find one of the 3 possible ways they could have written /proc/PROCNAME
|
||||
if(findtext(procname, "/proc/"))
|
||||
testname = replacetext(procname, "/proc/", "")
|
||||
else if(findtext(procname, "/proc"))
|
||||
testname = replacetext(procname, "/proc", "")
|
||||
else if(findtext(procname, "proc/"))
|
||||
testname = replacetext(procname, "proc/", "")
|
||||
//Clear out any parenthesis if they're a dummy
|
||||
testname = replacetext(testname, "()", "")
|
||||
|
||||
if(targetselected && !hascall(target,testname))
|
||||
to_chat(usr, "<font color='red'>Error: callproc(): type [target.type] has no proc named [procname].</font>")
|
||||
return
|
||||
else
|
||||
var/procpath = text2path(procname)
|
||||
if (!procpath)
|
||||
to_chat(usr, "<font color='red'>Error: callproc(): proc [procname] does not exist. (Did you forget the /proc/ part?)</font>")
|
||||
if(alert("Proc owned by something?",,"Yes","No") == "Yes")
|
||||
targetselected = TRUE
|
||||
var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT))
|
||||
if (!value["class"] || !value["value"])
|
||||
return
|
||||
target = value["value"]
|
||||
|
||||
var/procpath = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
|
||||
if(!procpath)
|
||||
return
|
||||
|
||||
//strip away everything but the proc name
|
||||
var/list/proclist = splittext(procpath, "/")
|
||||
if (!length(proclist))
|
||||
return
|
||||
|
||||
var/procname = proclist[proclist.len]
|
||||
var/proctype = ("verb" in proclist) ? "verb" :"proc"
|
||||
|
||||
if(targetselected)
|
||||
if(!hascall(target, procname))
|
||||
to_chat(usr, "<span class='warning'>Error: callproc(): type [target.type] has no [proctype] named [procpath].</span>")
|
||||
return
|
||||
else
|
||||
procpath = "/[proctype]/[procname]"
|
||||
if(!text2path(procpath))
|
||||
to_chat(usr, "<span class='warning'>Error: callproc(): [procpath] does not exist.</span>")
|
||||
return
|
||||
|
||||
var/list/lst = get_callproc_args()
|
||||
if(!lst)
|
||||
return
|
||||
|
||||
if(targetselected)
|
||||
if(!target)
|
||||
to_chat(usr, "<font color='red'>Error: callproc(): owner of proc no longer exists.</font>")
|
||||
to_chat(usr, "<span class='warning'>Error: callproc(): owner of proc no longer exists.</span>")
|
||||
return
|
||||
var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
|
||||
var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no argument"]."
|
||||
log_admin(msg)
|
||||
message_admins(msg)
|
||||
admin_ticket_log(target, msg)
|
||||
returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc
|
||||
returnval = WrapAdminProcCall(target, procname, lst)
|
||||
else
|
||||
//this currently has no hascall protection. wasn't able to get it working.
|
||||
log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
|
||||
message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
|
||||
returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc
|
||||
var/msg = "[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no argument"]."
|
||||
log_admin(msg)
|
||||
message_admins(msg)
|
||||
returnval = WrapAdminProcCall(GLOBAL_PROC, procpath, lst) //calling globals needs full qualified name (e.g /proc/foo)
|
||||
. = get_callproc_returnval(returnval, procname)
|
||||
if(.)
|
||||
to_chat(usr, .)
|
||||
@@ -111,8 +104,8 @@ GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention)
|
||||
GLOBAL_PROTECT(AdminProcCallSpamPrevention)
|
||||
|
||||
/proc/WrapAdminProcCall(datum/target, procname, list/arguments)
|
||||
if(target && procname == "Del")
|
||||
to_chat(usr, "Calling Del() is not allowed")
|
||||
if(target != GLOBAL_PROC && procname == "Del")
|
||||
to_chat(usr, "<span class='warning'>Calling Del() is not allowed</span>")
|
||||
return
|
||||
|
||||
if(target != GLOBAL_PROC && !target.CanProcCall(procname))
|
||||
@@ -159,7 +152,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
|
||||
/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf)
|
||||
set category = "Debug"
|
||||
set name = "Atom ProcCall"
|
||||
set waitfor = 0
|
||||
set waitfor = FALSE
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
@@ -168,7 +161,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
|
||||
if(!procname)
|
||||
return
|
||||
if(!hascall(A,procname))
|
||||
to_chat(usr, "<font color='red'>Error: callproc_datum(): type [A.type] has no proc named [procname].</font>")
|
||||
to_chat(usr, "<span class='warning'>Error: callproc_datum(): type [A.type] has no proc named [procname].</span>")
|
||||
return
|
||||
var/list/lst = get_callproc_args()
|
||||
if(!lst)
|
||||
@@ -177,8 +170,8 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
|
||||
if(!A || !IsValidSrc(A))
|
||||
to_chat(usr, "<span class='warning'>Error: callproc_datum(): owner of proc no longer exists.</span>")
|
||||
return
|
||||
log_admin("[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
|
||||
var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
|
||||
log_admin(msg)
|
||||
message_admins(msg)
|
||||
admin_ticket_log(A, msg)
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Atom ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
@@ -188,8 +181,6 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
|
||||
if(.)
|
||||
to_chat(usr, .)
|
||||
|
||||
|
||||
|
||||
/client/proc/get_callproc_args()
|
||||
var/argnum = input("Number of arguments","Number:",0) as num|null
|
||||
if(isnull(argnum))
|
||||
@@ -213,7 +204,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
|
||||
. = ""
|
||||
if(islist(returnval))
|
||||
var/list/returnedlist = returnval
|
||||
. = "<font color='blue'>"
|
||||
. = "<span class='notice'>"
|
||||
if(returnedlist.len)
|
||||
var/assoc_check = returnedlist[1]
|
||||
if(istext(assoc_check) && (returnedlist[assoc_check] != null))
|
||||
@@ -227,11 +218,10 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
|
||||
. += "\n[elem]"
|
||||
else
|
||||
. = "[procname] returned an empty list"
|
||||
. += "</font>"
|
||||
. += "</span>"
|
||||
|
||||
else
|
||||
. = "<font color='blue'>[procname] returned: [!isnull(returnval) ? returnval : "null"]</font>"
|
||||
|
||||
. = "<span class='notice'>[procname] returned: [!isnull(returnval) ? returnval : "null"]</span>"
|
||||
|
||||
/client/proc/Cell()
|
||||
set category = "Debug"
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
cross.icon_state = "kingyellow"
|
||||
font_color = "blue"
|
||||
prayer_type = "CHAPLAIN PRAYER"
|
||||
if(SSreligion.deity)
|
||||
deity = SSreligion.deity
|
||||
if(GLOB.deity)
|
||||
deity = GLOB.deity
|
||||
else if(iscultist(usr))
|
||||
cross.icon_state = "tome"
|
||||
font_color = "red"
|
||||
|
||||
@@ -126,8 +126,20 @@
|
||||
if(vest)
|
||||
vest.flip_mode()
|
||||
|
||||
/obj/machinery/abductor/console/proc/SelectDisguise(remote = 0)
|
||||
var/entry_name = input( "Choose Disguise", "Disguise") as null|anything in disguises
|
||||
/obj/machinery/abductor/console/proc/SelectDisguise(remote = FALSE)
|
||||
var/list/disguises2 = list()
|
||||
for(var/name in disguises)
|
||||
var/datum/icon_snapshot/snap = disguises[name]
|
||||
var/image/dummy = image(snap.icon, src, snap.icon_state)
|
||||
dummy.overlays = snap.overlays
|
||||
disguises2[name] = dummy
|
||||
|
||||
var/entry_name
|
||||
if(remote)
|
||||
entry_name = show_radial_menu(usr, camera.eyeobj, disguises2)
|
||||
else
|
||||
entry_name = show_radial_menu(usr, src, disguises2)
|
||||
|
||||
var/datum/icon_snapshot/chosen = disguises[entry_name]
|
||||
if(chosen && vest && (remote || in_range(usr,src)))
|
||||
vest.SetDisguise(chosen)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/obj/effect/proc_holder/changeling/adrenaline
|
||||
name = "Adrenaline Sacs"
|
||||
desc = "We evolve additional sacs of adrenaline throughout our body."
|
||||
helptext = "Removes all stuns instantly and adds a short-term reduction in further stuns. Can be used while unconscious. Continued use poisons the body."
|
||||
helptext = "Removes all stuns instantly and adds a short-term reduction in further stuns. Can be used while unconscious. Continued use poisons the body. This ability is loud, and might cause our blood to react violently to heat."
|
||||
chemical_cost = 30
|
||||
loudness = 2
|
||||
dna_cost = 2
|
||||
req_human = 1
|
||||
req_stat = UNCONSCIOUS
|
||||
@@ -13,4 +14,4 @@
|
||||
//Recover from stuns.
|
||||
/obj/effect/proc_holder/changeling/adrenaline/sting_action(mob/living/user)
|
||||
user.do_adrenaline(0, FALSE, 70, 0, TRUE, list("epinephrine" = 3, "changelingmeth" = 10, "mannitol" = 10, "regen_jelly" = 10, "changelingadrenaline" = 5), "<span class='notice'>Energy rushes through us.</span>", 0, 0.75, 0)
|
||||
return TRUE
|
||||
return TRUE
|
||||
@@ -29,7 +29,7 @@
|
||||
O.forceMove(get_turf(user))
|
||||
|
||||
user.reagents.add_reagent("mutadone", 10)
|
||||
user.reagents.add_reagent("pen_acid", 20)
|
||||
user.reagents.add_reagent("pen_jelly", 20)
|
||||
user.reagents.add_reagent("antihol", 10)
|
||||
user.reagents.add_reagent("mannitol", 25)
|
||||
|
||||
|
||||
@@ -342,10 +342,7 @@
|
||||
if(cooldown>world.time)
|
||||
to_chat(owner, "<span class='cultbold'>You aren't ready to place another blood mark yet!</span>")
|
||||
return
|
||||
if(owner.orbiting && owner.orbiting.orbiting)
|
||||
target = owner.orbiting.orbiting
|
||||
else
|
||||
target = get_turf(owner)
|
||||
target = owner.orbiting?.parent || get_turf(owner)
|
||||
if(!target)
|
||||
return
|
||||
C.cult_team.blood_target = target
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
visible_message("<span class='warning'>[src] easily breaks out of [p_their()] handcuffs!</span>", \
|
||||
"<span class='notice'>With just a thought your handcuffs fall off.</span>")
|
||||
|
||||
/mob/living/carbon/true_devil/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE)
|
||||
/mob/living/carbon/true_devil/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
|
||||
if(incapacitated())
|
||||
to_chat(src, "<span class='warning'>You can't do that right now!</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
cached_gases[/datum/gas/oxygen] -= cached_gases[/datum/gas/tritium]
|
||||
|
||||
if(burned_fuel)
|
||||
energy_released += FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel
|
||||
energy_released += (FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel)
|
||||
if(location && prob(10) && burned_fuel > TRITIUM_MINIMUM_RADIATION_ENERGY) //woah there let's not crash the server
|
||||
radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR)
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
if(do_explosion)
|
||||
explosion(location, 0, 0, 5, power_ratio, TRUE, TRUE) //large shockwave, the actual radius is quite small - people will recognize that you're doing fusion
|
||||
radiation_pulse(location, radiation_power) //You mean causing a super-tier fusion reaction in the halls is a bad idea?
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, 30000)//The science is cool though.
|
||||
playsound(location, 'sound/effects/supermatter.ogg', 100, 0)
|
||||
else
|
||||
playsound(location, 'sound/effects/phasein.ogg', 75, 0)
|
||||
@@ -350,12 +351,20 @@
|
||||
var/old_heat_capacity = air.heat_capacity()
|
||||
var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma]/cached_gases[/datum/gas/nitrous_oxide],1))),cached_gases[/datum/gas/nitrous_oxide],cached_gases[/datum/gas/plasma]/2)
|
||||
var/energy_released = 2*reaction_efficency*FIRE_CARBON_ENERGY_RELEASED
|
||||
if(cached_gases[/datum/gas/miasma] && cached_gases[/datum/gas/miasma] > 0)
|
||||
energy_released /= cached_gases[/datum/gas/miasma]*0.1
|
||||
if(cached_gases[/datum/gas/bz] && cached_gases[/datum/gas/bz] > 0)
|
||||
energy_released *= cached_gases[/datum/gas/bz]*0.1
|
||||
if ((cached_gases[/datum/gas/nitrous_oxide] - reaction_efficency < 0 )|| (cached_gases[/datum/gas/plasma] - (2*reaction_efficency) < 0)) //Shouldn't produce gas from nothing.
|
||||
return NO_REACTION
|
||||
cached_gases[/datum/gas/bz] += reaction_efficency
|
||||
if(reaction_efficency == cached_gases[/datum/gas/nitrous_oxide])
|
||||
cached_gases[/datum/gas/bz] -= min(pressure,1)
|
||||
cached_gases[/datum/gas/oxygen] += min(pressure,1)
|
||||
cached_gases[/datum/gas/nitrous_oxide] -= reaction_efficency
|
||||
cached_gases[/datum/gas/plasma] -= 2*reaction_efficency
|
||||
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, (reaction_efficency**0.5)*BZ_RESEARCH_AMOUNT)
|
||||
|
||||
if(energy_released > 0)
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
@@ -390,6 +399,7 @@
|
||||
cached_gases[/datum/gas/plasma] -= heat_scale
|
||||
cached_gases[/datum/gas/nitryl] -= heat_scale
|
||||
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, STIMULUM_RESEARCH_AMOUNT*max(stim_energy_change,0))
|
||||
if(stim_energy_change)
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
@@ -418,6 +428,7 @@
|
||||
cached_gases[/datum/gas/nitrogen] -= 20*nob_formed
|
||||
cached_gases[/datum/gas/hypernoblium]+= nob_formed
|
||||
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, nob_formed*NOBLIUM_RESEARCH_AMOUNT)
|
||||
|
||||
if (nob_formed)
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
@@ -449,3 +460,4 @@
|
||||
|
||||
//Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable
|
||||
air.temperature += cleaned_air * 0.002
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, cleaned_air*MIASMA_RESEARCH_AMOUNT)//Turns out the burning of miasma is kinda interesting to scientists
|
||||
@@ -68,6 +68,7 @@
|
||||
GLOB.poi_list |= src
|
||||
LAZYADD(GLOB.mob_spawners[job_description ? job_description : name], src)
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/Destroy()
|
||||
GLOB.poi_list -= src
|
||||
LAZYREMOVE(GLOB.mob_spawners[job_description ? job_description : name], src)
|
||||
@@ -75,6 +76,9 @@
|
||||
GLOB.mob_spawners -= job_description ? job_description : name
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/proc/can_latejoin() //If it can be taken from the lobby.
|
||||
return TRUE
|
||||
|
||||
/obj/effect/mob_spawn/proc/special(mob/M)
|
||||
return
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
var/obj/item/circuitboard/computer/cargo/board = circuit
|
||||
board.contraband = TRUE
|
||||
board.obj_flags |= EMAGGED
|
||||
req_access = list()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/cargo/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
|
||||
@@ -131,6 +131,24 @@
|
||||
unit_name = "security barrier"
|
||||
export_types = list(/obj/item/grenade/barrier, /obj/structure/barricade/security)
|
||||
|
||||
/datum/export/large/gas_canister
|
||||
cost = 10 //Base cost of canister. You get more for nice gases inside.
|
||||
unit_name = "Gas Canister"
|
||||
export_types = list(/obj/machinery/portable_atmospherics/canister)
|
||||
/datum/export/large/gas_canister/get_cost(obj/O)
|
||||
var/obj/machinery/portable_atmospherics/canister/C = O
|
||||
var/worth = 10
|
||||
var/gases = C.air_contents.gases
|
||||
|
||||
worth += gases[/datum/gas/bz]*4
|
||||
worth += gases[/datum/gas/stimulum]*25
|
||||
worth += gases[/datum/gas/hypernoblium]*1000
|
||||
worth += gases[/datum/gas/miasma]*15
|
||||
worth += gases[/datum/gas/tritium]*7
|
||||
worth += gases[/datum/gas/pluoxium]*6
|
||||
worth += gases[/datum/gas/nitryl]*30
|
||||
return worth
|
||||
|
||||
/datum/export/large/odysseus
|
||||
cost = 5500
|
||||
unit_name = "working odysseus"
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
var/obj/item/circuitboard/computer/cargo/board = circuit
|
||||
board.obj_flags |= EMAGGED
|
||||
packin_up()
|
||||
req_access = list()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/cargo/express/proc/packin_up() // oh shit, I'm sorry
|
||||
|
||||
@@ -755,13 +755,24 @@
|
||||
|
||||
/datum/supply_pack/engineering/engihardsuit
|
||||
name = "Engineering Hardsuit"
|
||||
desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and maks!"
|
||||
desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!"
|
||||
cost = 2500
|
||||
contains = list(/obj/item/tank/internals/air,
|
||||
/obj/item/clothing/mask/gas,
|
||||
/obj/item/clothing/suit/space/hardsuit/engine)
|
||||
crate_name = "engineering hardsuit"
|
||||
|
||||
/datum/supply_pack/engineering/atmoshardsuit
|
||||
name = "Atmospherics Hardsuit"
|
||||
desc = "Too many techs and not enough hardsuits? Time to buy some more! Comes with gas mask and air tank. Ask the CE to open."
|
||||
cost = 5000
|
||||
access = ACCESS_CE
|
||||
contains = list(/obj/item/tank/internals/air,
|
||||
/obj/item/clothing/mask/gas,
|
||||
/obj/item/clothing/suit/space/hardsuit/engine/atmos)
|
||||
crate_name = "atmospherics hardsuit"
|
||||
crate_type = /obj/structure/closet/crate/secure/engineering
|
||||
|
||||
/datum/supply_pack/engineering/industrialrcd
|
||||
name = "Industrial RCD"
|
||||
desc = "A industrial RCD in case the station has gone through more then one meteor storm and the CE needs to bring out the somthing a bit more reliable. Dose not contain spare ammo for the industrial RCD or any other RCD modles."
|
||||
@@ -1146,7 +1157,7 @@
|
||||
/datum/supply_pack/materials/bz
|
||||
name = "BZ Canister Crate"
|
||||
desc = "Contains a canister of BZ. Requires Toxins access to open."
|
||||
cost = 5000
|
||||
cost = 7500 // Costs 3 credits more than what you can get for selling it.
|
||||
access = ACCESS_TOX_STORAGE
|
||||
contains = list(/obj/machinery/portable_atmospherics/canister/bz)
|
||||
crate_name = "BZ canister crate"
|
||||
@@ -1949,6 +1960,17 @@
|
||||
crate_name = "hydroponics backpack crate"
|
||||
crate_type = /obj/structure/closet/crate/secure
|
||||
|
||||
/datum/supply_pack/organic/mre
|
||||
name = "MRE supply kit (emergency rations)"
|
||||
desc = "The lights are out. Oxygen's running low. You've run out of food except space weevils. Don't let this be you! Order our NT branded MRE kits today! This pack contains 5 MRE packs with a randomized menu and an oxygen tank."
|
||||
cost = 2000
|
||||
contains = list(/obj/item/storage/box/mre/menu1/safe,
|
||||
/obj/item/storage/box/mre/menu1/safe,
|
||||
/obj/item/storage/box/mre/menu2/safe,
|
||||
/obj/item/storage/box/mre/menu2/safe,
|
||||
/obj/item/storage/box/mre/menu3)
|
||||
crate_name = "MRE crate (emergency rations)"
|
||||
|
||||
/datum/supply_pack/organic/pizza
|
||||
name = "Pizza Crate"
|
||||
desc = "Best prices on this side of the galaxy. All deliveries are guaranteed to be 99% anomaly-free!"
|
||||
@@ -2241,7 +2263,8 @@
|
||||
/obj/item/storage/fancy/cigarettes/cigpack_shadyjims,
|
||||
/obj/item/clothing/mask/gas/syndicate,
|
||||
/obj/item/clothing/neck/necklace/dope,
|
||||
/obj/item/vending_refill/donksoft)
|
||||
/obj/item/vending_refill/donksoft,
|
||||
/obj/item/circuitboard/computer/arcade/amputation)
|
||||
crate_name = "crate"
|
||||
|
||||
/datum/supply_pack/costumes_toys/foamforce
|
||||
|
||||
@@ -467,6 +467,24 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
"stamp-law" = 'icons/stamp_icons/large_stamp-law.png'
|
||||
)
|
||||
|
||||
/datum/asset/spritesheet/simple/minesweeper
|
||||
name = "minesweeper"
|
||||
assets = list(
|
||||
"1" = 'icons/misc/minesweeper_tiles/one.png',
|
||||
"2" = 'icons/misc/minesweeper_tiles/two.png',
|
||||
"3" = 'icons/misc/minesweeper_tiles/three.png',
|
||||
"4" = 'icons/misc/minesweeper_tiles/four.png',
|
||||
"5" = 'icons/misc/minesweeper_tiles/five.png',
|
||||
"6" = 'icons/misc/minesweeper_tiles/six.png',
|
||||
"7" = 'icons/misc/minesweeper_tiles/seven.png',
|
||||
"8" = 'icons/misc/minesweeper_tiles/eight.png',
|
||||
"empty" = 'icons/misc/minesweeper_tiles/empty.png',
|
||||
"flag" = 'icons/misc/minesweeper_tiles/flag.png',
|
||||
"hidden" = 'icons/misc/minesweeper_tiles/hidden.png',
|
||||
"mine" = 'icons/misc/minesweeper_tiles/mine.png',
|
||||
"minehit" = 'icons/misc/minesweeper_tiles/minehit.png'
|
||||
)
|
||||
|
||||
/datum/asset/simple/IRV
|
||||
assets = list(
|
||||
"jquery-ui.custom-core-widgit-mouse-sortable-min.js" = 'html/IRV/jquery-ui.custom-core-widgit-mouse-sortable-min.js',
|
||||
|
||||
@@ -59,6 +59,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/preferred_map = null
|
||||
var/pda_style = MONO
|
||||
var/pda_color = "#808000"
|
||||
var/pda_skin = PDA_SKIN_ALT
|
||||
|
||||
var/uses_glasses_colour = 0
|
||||
|
||||
@@ -685,48 +686,48 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
else
|
||||
if(pref_species.use_skintones)
|
||||
dat += "<b>Genitals use skintone:</b><a href='?_src_=prefs;preference=genital_colour'>[features["genitals_use_skintone"] == TRUE ? "Yes" : "No"]</a>"
|
||||
dat += "<b>Has Penis:</b>"
|
||||
dat += "<h3>Penis</h3>"
|
||||
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_cock'>[features["has_cock"] == TRUE ? "Yes" : "No"]</a>"
|
||||
if(features["has_cock"] == TRUE)
|
||||
if(features["has_cock"])
|
||||
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
||||
dat += "<b>Penis Color:</b>"
|
||||
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)<br>"
|
||||
dat += "<b>Penis Color:</b></a><BR>"
|
||||
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)</a><br>"
|
||||
else
|
||||
dat += "<b>Penis Color:</b>"
|
||||
dat += "<b>Penis Color:</b></a><BR>"
|
||||
dat += "<span style='border: 1px solid #161616; background-color: #[features["cock_color"]];'> </span> <a href='?_src_=prefs;preference=cock_color;task=input'>Change</a><br>"
|
||||
dat += "<b>Penis Shape:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_shape;task=input'>[features["cock_shape"]]</a>"
|
||||
dat += "<b>Penis Length:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_length;task=input'>[features["cock_length"]] inch(es)</a>"
|
||||
dat += "<b>Has Testicles:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=has_balls'>[features["has_balls"] == TRUE ? "Yes" : "No"]</a>"
|
||||
if(features["has_balls"] == TRUE)
|
||||
if(features["has_balls"])
|
||||
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
||||
dat += "<b>Testicles Color:</b>"
|
||||
dat += "<b>Testicles Color:</b></a><BR>"
|
||||
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)<br>"
|
||||
else
|
||||
dat += "<b>Testicles Color:</b>"
|
||||
dat += "<b>Testicles Color:</b></a><BR>"
|
||||
dat += "<span style='border: 1px solid #161616; background-color: #[features["balls_color"]];'> </span> <a href='?_src_=prefs;preference=balls_color;task=input'>Change</a><br>"
|
||||
dat += "<b>Testicles showing:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=balls_shape;task=input'>[features["balls_shape"]]</a>"
|
||||
dat += APPEARANCE_CATEGORY_COLUMN
|
||||
dat += "<b>Has Vagina:</b>"
|
||||
dat += "<h3>Vagina</h3>"
|
||||
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_vag'>[features["has_vag"] == TRUE ? "Yes" : "No"]</a>"
|
||||
if(features["has_vag"])
|
||||
dat += "<b>Vagina Type:</b> <a style='display:block;width:100px' href='?_src_=prefs;preference=vag_shape;task=input'>[features["vag_shape"]]</a>"
|
||||
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
||||
dat += "<b>Vagina Color:</b>"
|
||||
dat += "<b>Vagina Color:</b></a><BR>"
|
||||
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)<br>"
|
||||
else
|
||||
dat += "<b>Vagina Color:</b>"
|
||||
dat += "<b>Vagina Color:</b></a><BR>"
|
||||
dat += "<span style='border: 1px solid #161616; background-color: #[features["vag_color"]];'> </span> <a href='?_src_=prefs;preference=vag_color;task=input'>Change</a><br>"
|
||||
dat += "<b>Has Womb:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=has_womb'>[features["has_womb"] == TRUE ? "Yes" : "No"]</a>"
|
||||
dat += "</td>"
|
||||
dat += APPEARANCE_CATEGORY_COLUMN
|
||||
dat += "<b>Has Breasts:</b>"
|
||||
dat += "<h3>Breasts</h3>"
|
||||
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_breasts'>[features["has_breasts"] == TRUE ? "Yes" : "No"]</a>"
|
||||
if(features["has_breasts"])
|
||||
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
||||
dat += "<b>Color:</b>"
|
||||
dat += "<b>Color:</b></a><BR>"
|
||||
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)<br>"
|
||||
else
|
||||
dat += "<b>Color:</b>"
|
||||
dat += "<b>Color:</b></a><BR>"
|
||||
dat += "<span style='border: 1px solid #161616; background-color: #[features["breasts_color"]];'> </span> <a href='?_src_=prefs;preference=breasts_color;task=input'>Change</a><br>"
|
||||
dat += "<b>Cup Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_size;task=input'>[features["breasts_size"]]</a>"
|
||||
dat += "<b>Breast Shape:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_shape;task=input'>[features["breasts_shape"]]</a>"
|
||||
@@ -746,6 +747,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<br>"
|
||||
dat += "<b>PDA Color:</b> <span style='border:1px solid #161616; background-color: [pda_color];'> </span> <a href='?_src_=prefs;preference=pda_color;task=input'>Change</a><BR>"
|
||||
dat += "<b>PDA Style:</b> <a href='?_src_=prefs;task=input;preference=pda_style'>[pda_style]</a><br>"
|
||||
dat += "<b>PDA Reskin:</b> <a href='?_src_=prefs;task=input;preference=pda_skin'>[pda_skin]</a><br>"
|
||||
dat += "<br>"
|
||||
dat += "<b>Ghost Ears:</b> <a href='?_src_=prefs;preference=ghost_ears'>[(chat_toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</a><br>"
|
||||
dat += "<b>Ghost Radio:</b> <a href='?_src_=prefs;preference=ghost_radio'>[(chat_toggles & CHAT_GHOSTRADIO) ? "All Messages":"No Messages"]</a><br>"
|
||||
@@ -1986,6 +1988,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/pickedPDAColor = input(user, "Choose your PDA Interface color.", "Character Preference",pda_color) as color|null
|
||||
if(pickedPDAColor)
|
||||
pda_color = pickedPDAColor
|
||||
if("pda_skin")
|
||||
var/pickedPDASkin = input(user, "Choose your PDA reskin.", "Character Preference", pda_skin) as null|anything in GLOB.pda_reskins
|
||||
if(pickedPDASkin)
|
||||
pda_skin = pickedPDASkin
|
||||
|
||||
else
|
||||
switch(href_list["preference"])
|
||||
@@ -1996,6 +2002,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
arousable = !arousable
|
||||
if("has_cock")
|
||||
features["has_cock"] = !features["has_cock"]
|
||||
if(features["has_cock"] == FALSE)
|
||||
features["has_balls"] = FALSE
|
||||
if("has_balls")
|
||||
features["has_balls"] = !features["has_balls"]
|
||||
if("has_ovi")
|
||||
@@ -2010,6 +2018,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
features["has_breasts"] = !features["has_breasts"]
|
||||
if("has_vag")
|
||||
features["has_vag"] = !features["has_vag"]
|
||||
if(features["has_vag"] == FALSE)
|
||||
features["has_womb"] = FALSE
|
||||
if("has_womb")
|
||||
features["has_womb"] = !features["has_womb"]
|
||||
if("exhibitionist")
|
||||
@@ -2236,8 +2246,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
character.hair_style = hair_style
|
||||
character.facial_hair_style = facial_hair_style
|
||||
character.underwear = underwear
|
||||
character.saved_underwear = underwear
|
||||
character.undershirt = undershirt
|
||||
character.saved_undershirt = undershirt
|
||||
character.socks = socks
|
||||
character.saved_socks = socks
|
||||
|
||||
character.backbag = backbag
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["tip_delay"] >> tip_delay
|
||||
S["pda_style"] >> pda_style
|
||||
S["pda_color"] >> pda_color
|
||||
S["pda_skin"] >> pda_skin
|
||||
|
||||
//citadel code
|
||||
S["arousable"] >> arousable
|
||||
@@ -144,6 +145,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
be_special = SANITIZE_LIST(be_special)
|
||||
pda_style = sanitize_inlist(pda_style, GLOB.pda_styles, initial(pda_style))
|
||||
pda_color = sanitize_hexcolor(pda_color, 6, 1, initial(pda_color))
|
||||
pda_skin = sanitize_inlist(pda_skin, GLOB.pda_reskins, PDA_SKIN_ALT)
|
||||
|
||||
screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake))
|
||||
damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake))
|
||||
|
||||
@@ -226,6 +226,19 @@
|
||||
CL.flags_cover = initial(PCL.flags_cover)
|
||||
target.icon = initial(picked_item.icon)
|
||||
|
||||
/datum/action/item_action/chameleon/change/pda/update_item(obj/item/pda/picked_item)
|
||||
if(!istype(target, /obj/item/pda))
|
||||
return ..()
|
||||
var/obj/item/pda/P = target
|
||||
P.name = initial(picked_item.name)
|
||||
P.desc = initial(picked_item.desc)
|
||||
P.icon_state = initial(picked_item.icon_state)
|
||||
P.item_state = initial(picked_item.item_state)
|
||||
P.item_color = initial(picked_item.item_color)
|
||||
P.overlays_offsets = initial(picked_item.overlays_offsets)
|
||||
P.set_new_overlays()
|
||||
P.update_icon()
|
||||
|
||||
/datum/action/item_action/chameleon/change/Trigger()
|
||||
if(!IsAvailable())
|
||||
return
|
||||
@@ -584,7 +597,7 @@
|
||||
|
||||
/obj/item/pda/chameleon
|
||||
name = "PDA"
|
||||
var/datum/action/item_action/chameleon/change/chameleon_action
|
||||
var/datum/action/item_action/chameleon/change/pda/chameleon_action
|
||||
|
||||
/obj/item/pda/chameleon/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -216,6 +216,34 @@ BLIND // can't see anything
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/clothing/under/CtrlClick(mob/user)
|
||||
. = ..()
|
||||
|
||||
if (!(item_flags & IN_INVENTORY))
|
||||
return
|
||||
|
||||
if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
return
|
||||
|
||||
if(has_sensor == LOCKED_SENSORS)
|
||||
to_chat(user, "The controls are locked.")
|
||||
return
|
||||
if(has_sensor == BROKEN_SENSORS)
|
||||
to_chat(user, "The sensors have shorted out!")
|
||||
return
|
||||
if(has_sensor <= NO_SENSORS)
|
||||
to_chat(user, "This suit does not have any sensors.")
|
||||
return
|
||||
|
||||
sensor_mode = SENSOR_COORDS
|
||||
|
||||
to_chat(user, "<span class='notice'>Your suit will now report your exact vital lifesigns as well as your coordinate position.</span>")
|
||||
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.w_uniform == src)
|
||||
H.update_suit_sensors()
|
||||
|
||||
/obj/item/clothing/under/AltClick(mob/user)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
desc = "A pair of snazzy goggles used to protect against chemical spills. Fitted with an analyzer for scanning items and reagents."
|
||||
icon_state = "purple"
|
||||
item_state = "glasses"
|
||||
scan_reagents = 1 //You can see reagents while wearing science goggles
|
||||
scan_reagents = TRUE //You can see reagents while wearing science goggles
|
||||
actions_types = list(/datum/action/item_action/toggle_research_scanner)
|
||||
glass_colour_type = /datum/client_colour/glass_colour/purple
|
||||
resistance_flags = ACID_PROOF
|
||||
@@ -202,7 +202,7 @@
|
||||
/obj/item/clothing/glasses/sunglasses/reagent
|
||||
name = "beer goggles"
|
||||
desc = "A pair of sunglasses outfitted with apparatus to scan reagents."
|
||||
scan_reagents = 1
|
||||
scan_reagents = TRUE
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/garb
|
||||
name = "black gar glasses"
|
||||
@@ -377,7 +377,7 @@
|
||||
item_state = "godeye"
|
||||
vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS
|
||||
darkness_view = 8
|
||||
scan_reagents = 1
|
||||
scan_reagents = TRUE
|
||||
item_flags = NODROP
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF
|
||||
|
||||
@@ -445,7 +445,7 @@
|
||||
flash_protect = 0
|
||||
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75)
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
|
||||
scan_reagents = 1
|
||||
scan_reagents = TRUE
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/medical
|
||||
icon_state = "hardsuit-medical"
|
||||
@@ -467,7 +467,7 @@
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80)
|
||||
var/obj/machinery/doppler_array/integrated/bomb_radar
|
||||
scan_reagents = 1
|
||||
scan_reagents = TRUE
|
||||
actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_research_scanner)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/rd/Initialize()
|
||||
@@ -626,7 +626,7 @@
|
||||
item_state = "anc_hardsuit"
|
||||
armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 500, "bomb" = 500, "bio" = 500, "rad" = 500, "fire" = 500, "acid" = 500)
|
||||
slowdown = 6 //Slow
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage, /obj/item/construction/rcd, /obj/item/pipe_dispenser)
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage, /obj/item/construction/rcd, /obj/item/pipe_dispenser)
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
@@ -639,7 +639,7 @@
|
||||
armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 500, "bomb" = 500, "bio" = 500, "rad" = 500, "fire" = 500, "acid" = 500)
|
||||
item_color = "ancient"
|
||||
brightness_on = 16
|
||||
scan_reagents = 1
|
||||
scan_reagents = TRUE
|
||||
flash_protect = 5 //We will not be flash by bombs
|
||||
tint = 1
|
||||
var/obj/machinery/doppler_array/integrated/bomb_radar
|
||||
|
||||
@@ -58,7 +58,8 @@
|
||||
item_state = "hostrench"
|
||||
flags_inv = 0
|
||||
strip_delay = 80
|
||||
|
||||
unique_reskin = list("Coat" = "hostrench", "Cloak" = "trenchcloak")
|
||||
|
||||
/obj/item/clothing/suit/armor/vest/warden
|
||||
name = "warden's jacket"
|
||||
desc = "A navy-blue armored jacket with blue shoulder designations and '/Warden/' stitched into one of the chest pockets."
|
||||
|
||||
@@ -124,6 +124,9 @@
|
||||
icon_state = "suitjacket_black"
|
||||
item_state = "ro_suit"
|
||||
|
||||
/obj/item/clothing/suit/toggle/lawyer/black/syndie
|
||||
desc = "A snappy dress jacket. Suspiciously has no tags or branding."
|
||||
armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40)
|
||||
|
||||
//Mime
|
||||
/obj/item/clothing/suit/suspenders
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,7 @@
|
||||
CAT_BURGER,
|
||||
CAT_CAKE,
|
||||
CAT_EGG,
|
||||
CAT_SUSHI, //Called Fish
|
||||
CAT_FISH,
|
||||
CAT_ICE, //Called Frozen
|
||||
CAT_MEAT,
|
||||
CAT_MISCFOOD,
|
||||
|
||||
@@ -365,28 +365,6 @@
|
||||
parts = list(/obj/item/camera = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/lizardhat
|
||||
name = "Lizard Cloche Hat"
|
||||
result = /obj/item/clothing/head/lizard
|
||||
time = 10
|
||||
reqs = list(/obj/item/organ/tail/lizard = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/lizardhat_alternate
|
||||
name = "Lizard Cloche Hat"
|
||||
result = /obj/item/clothing/head/lizard
|
||||
time = 10
|
||||
reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/kittyears
|
||||
name = "Kitty Ears"
|
||||
result = /obj/item/clothing/head/kitty/genuine
|
||||
time = 10
|
||||
reqs = list(/obj/item/organ/tail/cat = 1,
|
||||
/obj/item/organ/ears/cat = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/skateboard
|
||||
name = "Skateboard"
|
||||
result = /obj/vehicle/ridden/scooter/skateboard
|
||||
@@ -641,6 +619,15 @@
|
||||
/obj/item/assembly/igniter = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
|
||||
/datum/crafting_recipe/wheelchair
|
||||
name = "Wheelchair"
|
||||
result = /obj/vehicle/ridden/wheelchair
|
||||
reqs = list(/obj/item/stack/sheet/plasteel = 2,
|
||||
/obj/item/stack/rods = 8)
|
||||
time = 100
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/rcl
|
||||
name = "Makeshift Rapid Cable Layer"
|
||||
result = /obj/item/twohanded/rcl/ghetto
|
||||
@@ -672,6 +659,28 @@
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/lizardhat
|
||||
name = "Lizard Cloche Hat"
|
||||
result = /obj/item/clothing/head/lizard
|
||||
time = 10
|
||||
reqs = list(/obj/item/organ/tail/lizard = 1)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/lizardhat_alternate
|
||||
name = "Lizard Cloche Hat"
|
||||
result = /obj/item/clothing/head/lizard
|
||||
time = 10
|
||||
reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/kittyears
|
||||
name = "Kitty Ears"
|
||||
result = /obj/item/clothing/head/kitty/genuine
|
||||
time = 10
|
||||
reqs = list(/obj/item/organ/tail/cat = 1,
|
||||
/obj/item/organ/ears/cat = 1)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudsunsec
|
||||
name = "Security HUDsunglasses"
|
||||
result = /obj/item/clothing/glasses/hud/security/sunglasses
|
||||
@@ -781,3 +790,36 @@
|
||||
/datum/reagent/water = 15)
|
||||
time = 40
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/smartdart
|
||||
name = "Medical smartdart"
|
||||
result = /obj/item/reagent_containers/syringe/dart
|
||||
reqs = list(/obj/item/stack/sheet/metal = 1,
|
||||
/obj/item/stack/sheet/glass = 1,
|
||||
/obj/item/stack/sheet/plastic = 1)
|
||||
time = 10
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_AMMO
|
||||
|
||||
/datum/crafting_recipe/medolier
|
||||
name = "Medolier"
|
||||
result = /obj/item/storage/belt/medolier
|
||||
reqs = list(/obj/item/stack/sheet/metal = 2,
|
||||
/obj/item/stack/sheet/cloth = 3,
|
||||
/obj/item/stack/sheet/plastic = 4)
|
||||
time = 30
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_AMMO
|
||||
|
||||
/datum/crafting_recipe/smartdartgun
|
||||
name = "Smart dartgun"
|
||||
result = /obj/item/gun/syringe/dart
|
||||
reqs = list(/obj/item/stack/sheet/metal = 15,
|
||||
/obj/item/stack/sheet/glass = 10,
|
||||
/obj/item/tank/internals = 1,
|
||||
/obj/item/reagent_containers/glass/beaker = 1,
|
||||
/obj/item/stack/sheet/plastic = 10,
|
||||
/obj/item/stack/cable_coil = 2)
|
||||
time = 150 //It's a gun
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
|
||||
@@ -204,6 +204,14 @@
|
||||
resistance_flags = FREEZE_PROOF
|
||||
isGlass = FALSE
|
||||
|
||||
//Used by MREs
|
||||
/obj/item/reagent_containers/food/drinks/coffee/type2
|
||||
name = "\improper Coffee, instant (type 2)"
|
||||
desc = "Coffee that's been blow dried into a granulated powder. This packet includes self heating water for your nutritional pleasure."
|
||||
icon = 'icons/obj/food/containers.dmi'
|
||||
icon_state = "condi_cornoil"
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/ice
|
||||
name = "ice cup"
|
||||
desc = "Careful, cold ice, do not chew."
|
||||
|
||||
@@ -291,19 +291,23 @@ All foods are distributed among various categories. Use common sense.
|
||||
S.reagents.add_reagent(r_id, amount)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/microwave_act(obj/machinery/microwave/M)
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/item/result
|
||||
if(cooked_type)
|
||||
var/obj/item/reagent_containers/food/snacks/S = new cooked_type(get_turf(src))
|
||||
if(M)
|
||||
initialize_cooked_food(S, M.efficiency)
|
||||
result = new cooked_type(T)
|
||||
if(istype(M))
|
||||
initialize_cooked_food(result, M.efficiency)
|
||||
else
|
||||
initialize_cooked_food(S, 1)
|
||||
SSblackbox.record_feedback("tally", "food_made", 1, type)
|
||||
initialize_cooked_food(result, 1)
|
||||
SSblackbox.record_feedback("tally", "food_made", 1, result.type)
|
||||
else
|
||||
new /obj/item/reagent_containers/food/snacks/badrecipe(src)
|
||||
if(M && M.dirty < 100)
|
||||
result = new /obj/item/reagent_containers/food/snacks/badrecipe(T)
|
||||
if(istype(M) && M.dirty < 100)
|
||||
M.dirty++
|
||||
qdel(src)
|
||||
|
||||
return result
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/Destroy()
|
||||
if(contents)
|
||||
for(var/atom/movable/something in contents)
|
||||
|
||||
@@ -225,3 +225,12 @@
|
||||
filling_color = "#FFFFFF"
|
||||
foodtype = GRAIN | VEGETABLES
|
||||
|
||||
|
||||
// Used by MREs
|
||||
/obj/item/reagent_containers/food/snacks/pizzaslice/pepperoni
|
||||
name = "\improper MRE pepperoni pizza slice"
|
||||
desc = "A freeze dried, dehydrated slice of bread with tomato sauce, pepperoni and cheese."
|
||||
icon_state = "meatpizzaslice"
|
||||
filling_color = "#A52A2A"
|
||||
tastes = list("cardboard" = 1, "tomato" = 1, "cheese" = 1, "pepperoni" = 2)
|
||||
foodtype = GRAIN | VEGETABLES | DAIRY | MEAT
|
||||
@@ -12,322 +12,343 @@
|
||||
pass_flags = PASSTABLE
|
||||
light_color = LIGHT_COLOR_YELLOW
|
||||
light_power = 0.9
|
||||
var/wire_disabled = FALSE // is its internal wire cut?
|
||||
var/operating = FALSE // Is it on?
|
||||
var/dirty = 0 // = {0..100} Does it need cleaning?
|
||||
var/broken = 0 // ={0,1,2} How broken is it???
|
||||
var/max_n_of_items = 10 // whatever fat fuck made this a global var needs to look at themselves in the mirror sometime
|
||||
var/dirty = 0 // 0 to 100 // Does it need cleaning?
|
||||
var/dirty_anim_playing = FALSE
|
||||
var/broken = 0 // 0, 1 or 2 // How broken is it???
|
||||
var/max_n_of_items = 10
|
||||
var/efficiency = 0
|
||||
var/datum/looping_sound/microwave/soundloop
|
||||
var/list/ingredients = list() // may only contain /atom/movables
|
||||
|
||||
//Microwaving doesn't use recipes, instead it calls the microwave_act of the objects. For food, this creates something based on the food's cooked_type
|
||||
var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine")
|
||||
var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject")
|
||||
var/static/radial_use = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_use")
|
||||
|
||||
/*******************
|
||||
* Initialising
|
||||
********************/
|
||||
// we show the button even if the proc will not work
|
||||
var/static/list/radial_options = list("eject" = radial_eject, "use" = radial_use)
|
||||
var/static/list/ai_radial_options = list("eject" = radial_eject, "use" = radial_use, "examine" = radial_examine)
|
||||
|
||||
/obj/machinery/microwave/Initialize()
|
||||
. = ..()
|
||||
wires = new /datum/wires/microwave(src)
|
||||
create_reagents(100)
|
||||
soundloop = new(list(src), FALSE)
|
||||
|
||||
/obj/machinery/microwave/Destroy()
|
||||
eject()
|
||||
if(wires)
|
||||
QDEL_NULL(wires)
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/microwave/RefreshParts()
|
||||
var/E
|
||||
var/max_items = 10
|
||||
efficiency = 0
|
||||
for(var/obj/item/stock_parts/micro_laser/M in component_parts)
|
||||
E += M.rating
|
||||
efficiency += M.rating
|
||||
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
|
||||
max_items = 10 * M.rating
|
||||
efficiency = E
|
||||
max_n_of_items = max_items
|
||||
max_n_of_items = 10 * M.rating
|
||||
break
|
||||
|
||||
/obj/machinery/microwave/examine(mob/user)
|
||||
..()
|
||||
. = ..()
|
||||
if(!operating)
|
||||
to_chat(user, "<span class='notice'>Alt-click [src] to turn it on.</span>")
|
||||
|
||||
/*******************
|
||||
* Item Adding
|
||||
********************/
|
||||
if(!in_range(user, src) && !issilicon(user) && !isobserver(user))
|
||||
to_chat(user, "<span class='warning'>You're too far away to examine [src]'s contents and display!</span>")
|
||||
return
|
||||
if(operating)
|
||||
to_chat(user, "<span class='notice'>\The [src] is operating.</span>")
|
||||
return
|
||||
|
||||
if(length(ingredients))
|
||||
if(issilicon(user))
|
||||
to_chat(user, "<span class='notice'>\The [src] camera shows:</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\The [src] contains:</span>")
|
||||
var/list/items_counts = new
|
||||
for(var/i in ingredients)
|
||||
if(istype(i, /obj/item/stack))
|
||||
var/obj/item/stack/S = i
|
||||
items_counts[S.name] += S.amount
|
||||
else
|
||||
var/atom/movable/AM = i
|
||||
items_counts[AM.name]++
|
||||
for(var/O in items_counts)
|
||||
to_chat(user, "<span class='notice'>- [items_counts[O]]x [O].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\The [src] is empty.</span>")
|
||||
|
||||
if(!(stat & (NOPOWER|BROKEN)))
|
||||
to_chat(user, "<span class='notice'>The status display reads:</span>")
|
||||
to_chat(user, "<span class='notice'>- Capacity: <b>[max_n_of_items]</b> items.<span>")
|
||||
to_chat(user, "<span class='notice'>- Cook time reduced by <b>[(efficiency - 1) * 25]%</b>.<span>")
|
||||
|
||||
/obj/machinery/microwave/update_icon()
|
||||
if(broken)
|
||||
icon_state = "mwb"
|
||||
else if(dirty_anim_playing)
|
||||
icon_state = "mwbloody1"
|
||||
else if(dirty == 100)
|
||||
icon_state = "mwbloody"
|
||||
else if(operating)
|
||||
icon_state = "mw1"
|
||||
else if(panel_open)
|
||||
icon_state = "mw-o"
|
||||
else
|
||||
icon_state = "mw"
|
||||
|
||||
/obj/machinery/microwave/attackby(obj/item/O, mob/user, params)
|
||||
if(operating)
|
||||
return
|
||||
if(!broken && dirty<100)
|
||||
if(default_deconstruction_screwdriver(user, "mw-o", "mw", O))
|
||||
return
|
||||
if(default_unfasten_wrench(user, O))
|
||||
return
|
||||
|
||||
if(default_deconstruction_crowbar(O))
|
||||
return
|
||||
|
||||
if(src.broken > 0)
|
||||
if(src.broken == 2 && istype(O, /obj/item/wirecutters)) // If it's broken and they're using a screwdriver
|
||||
user.visible_message( \
|
||||
"[user] starts to fix part of the microwave.", \
|
||||
"<span class='notice'>You start to fix part of the microwave...</span>" \
|
||||
)
|
||||
if (O.use_tool(src, user, 20))
|
||||
user.visible_message( \
|
||||
"[user] fixes part of the microwave.", \
|
||||
"<span class='notice'>You fix part of the microwave.</span>" \
|
||||
)
|
||||
src.broken = 1 // Fix it a bit
|
||||
else if(src.broken == 1 && istype(O, /obj/item/weldingtool)) // If it's broken and they're doing the wrench
|
||||
user.visible_message( \
|
||||
"[user] starts to fix part of the microwave.", \
|
||||
"<span class='notice'>You start to fix part of the microwave...</span>" \
|
||||
)
|
||||
if (O.use_tool(src, user, 20))
|
||||
user.visible_message( \
|
||||
"[user] fixes the microwave.", \
|
||||
"<span class='notice'>You fix the microwave.</span>" \
|
||||
)
|
||||
src.icon_state = "mw"
|
||||
src.broken = 0 // Fix it!
|
||||
src.dirty = 0 // just to be sure
|
||||
return 0 //to use some fuel
|
||||
if(dirty < 100)
|
||||
if(default_deconstruction_screwdriver(user, icon_state, icon_state, O) || default_unfasten_wrench(user, O))
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(panel_open && is_wire_tool(O))
|
||||
wires.interact(user)
|
||||
return TRUE
|
||||
|
||||
if(broken > 0)
|
||||
if(broken == 2 && O.tool_behaviour == TOOL_WIRECUTTER) // If it's broken and they're using a screwdriver
|
||||
user.visible_message("[user] starts to fix part of \the [src].", "<span class='notice'>You start to fix part of \the [src]...</span>")
|
||||
if(O.use_tool(src, user, 20))
|
||||
user.visible_message("[user] fixes part of \the [src].", "<span class='notice'>You fix part of \the [src].</span>")
|
||||
broken = 1 // Fix it a bit
|
||||
else if(broken == 1 && O.tool_behaviour == TOOL_WELDER) // If it's broken and they're doing the wrench
|
||||
user.visible_message("[user] starts to fix part of \the [src].", "<span class='notice'>You start to fix part of \the [src]...</span>")
|
||||
if(O.use_tool(src, user, 20))
|
||||
user.visible_message("[user] fixes \the [src].", "<span class='notice'>You fix \the [src].</span>")
|
||||
broken = 0
|
||||
update_icon()
|
||||
return FALSE //to use some fuel
|
||||
else
|
||||
to_chat(user, "<span class='warning'>It's broken!</span>")
|
||||
return 1
|
||||
else if(istype(O, /obj/item/reagent_containers/spray/))
|
||||
return TRUE
|
||||
return
|
||||
|
||||
if(istype(O, /obj/item/reagent_containers/spray))
|
||||
var/obj/item/reagent_containers/spray/clean_spray = O
|
||||
if(clean_spray.reagents.has_reagent("cleaner",clean_spray.amount_per_transfer_from_this))
|
||||
clean_spray.reagents.remove_reagent("cleaner",clean_spray.amount_per_transfer_from_this,1)
|
||||
if(clean_spray.reagents.has_reagent("cleaner", clean_spray.amount_per_transfer_from_this))
|
||||
clean_spray.reagents.remove_reagent("cleaner", clean_spray.amount_per_transfer_from_this,1)
|
||||
playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6)
|
||||
user.visible_message( \
|
||||
"[user] has cleaned the microwave.", \
|
||||
"<span class='notice'>You clean the microwave.</span>" \
|
||||
)
|
||||
src.dirty = 0 // It's clean!
|
||||
src.broken = 0 // just to be sure
|
||||
src.icon_state = "mw"
|
||||
src.updateUsrDialog()
|
||||
return 1 // Disables the after-attack so we don't spray the floor/user.
|
||||
user.visible_message("[user] has cleaned \the [src].", "<span class='notice'>You clean \the [src].</span>")
|
||||
dirty = 0
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need more space cleaner!</span>")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
else if(istype(O, /obj/item/soap/)) // If they're trying to clean it then let them
|
||||
if(istype(O, /obj/item/soap))
|
||||
var/obj/item/soap/P = O
|
||||
user.visible_message( \
|
||||
"[user] starts to clean the microwave.", \
|
||||
"<span class='notice'>You start to clean the microwave...</span>" \
|
||||
)
|
||||
if (do_after(user, P.cleanspeed, target = src))
|
||||
user.visible_message( \
|
||||
"[user] has cleaned the microwave.", \
|
||||
"<span class='notice'>You clean the microwave.</span>" \
|
||||
)
|
||||
src.dirty = 0 // It's clean!
|
||||
src.broken = 0 // just to be sure
|
||||
src.icon_state = "mw"
|
||||
user.visible_message("[user] starts to clean \the [src].", "<span class='notice'>You start to clean \the [src]...</span>")
|
||||
if(do_after(user, P.cleanspeed, target = src))
|
||||
user.visible_message("[user] has cleaned \the [src].", "<span class='notice'>You clean \the [src].</span>")
|
||||
dirty = 0
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
else if(src.dirty==100) // The microwave is all dirty so can't be used!
|
||||
to_chat(user, "<span class='warning'>It's dirty!</span>")
|
||||
return 1
|
||||
if(dirty == 100) // The microwave is all dirty so can't be used!
|
||||
to_chat(user, "<span class='warning'>\The [src] is dirty!</span>")
|
||||
return TRUE
|
||||
|
||||
else if(istype(O, /obj/item/storage/bag/tray))
|
||||
if(istype(O, /obj/item/storage/bag/tray))
|
||||
var/obj/item/storage/T = O
|
||||
var/loaded = 0
|
||||
for(var/obj/item/reagent_containers/food/snacks/S in T.contents)
|
||||
if (contents.len>=max_n_of_items)
|
||||
to_chat(user, "<span class='warning'>[src] is full, you can't put anything in!</span>")
|
||||
return 1
|
||||
if(ingredients.len >= max_n_of_items)
|
||||
to_chat(user, "<span class='warning'>\The [src] is full, you can't put anything in!</span>")
|
||||
return TRUE
|
||||
if(SEND_SIGNAL(T, COMSIG_TRY_STORAGE_TAKE, S, src))
|
||||
loaded++
|
||||
|
||||
ingredients += S
|
||||
if(loaded)
|
||||
to_chat(user, "<span class='notice'>You insert [loaded] items into [src].</span>")
|
||||
to_chat(user, "<span class='notice'>You insert [loaded] items into \the [src].</span>")
|
||||
return
|
||||
|
||||
if(O.w_class <= WEIGHT_CLASS_NORMAL && !istype(O, /obj/item/storage) && user.a_intent == INTENT_HELP)
|
||||
if(ingredients.len >= max_n_of_items)
|
||||
to_chat(user, "<span class='warning'>\The [src] is full, you can't put anything in!</span>")
|
||||
return TRUE
|
||||
if(!user.transferItemToLoc(O, src))
|
||||
to_chat(user, "<span class='warning'>\The [O] is stuck to your hand!</span>")
|
||||
return FALSE
|
||||
|
||||
else if(O.w_class <= WEIGHT_CLASS_NORMAL && !istype(O, /obj/item/storage) && user.a_intent == INTENT_HELP)
|
||||
if (contents.len>=max_n_of_items)
|
||||
to_chat(user, "<span class='warning'>[src] is full, you can't put anything in!</span>")
|
||||
return 1
|
||||
else
|
||||
if(!user.transferItemToLoc(O, src))
|
||||
to_chat(user, "<span class='warning'>\the [O] is stuck to your hand, you cannot put it in \the [src]!</span>")
|
||||
return 0
|
||||
ingredients += O
|
||||
user.visible_message("[user] has added \a [O] to \the [src].", "<span class='notice'>You add [O] to \the [src].</span>")
|
||||
return
|
||||
|
||||
user.visible_message( \
|
||||
"[user] has added \the [O] to \the [src].", \
|
||||
"<span class='notice'>You add \the [O] to \the [src].</span>")
|
||||
|
||||
else
|
||||
..()
|
||||
updateUsrDialog()
|
||||
..()
|
||||
|
||||
/obj/machinery/microwave/AltClick(mob/user)
|
||||
if(user.canUseTopic(src, BE_CLOSE) && !(operating || broken > 0 || panel_open || !anchored || dirty == 100))
|
||||
if(user.canUseTopic(src, !issilicon(usr)))
|
||||
cook()
|
||||
|
||||
/*******************
|
||||
* Microwave Menu
|
||||
********************/
|
||||
|
||||
/obj/machinery/microwave/ui_interact(mob/user) // The microwave Menu
|
||||
/obj/machinery/microwave/ui_interact(mob/user)
|
||||
. = ..()
|
||||
if(panel_open || !anchored)
|
||||
|
||||
if(operating || panel_open || !anchored || !user.canUseTopic(src, !issilicon(user)))
|
||||
return
|
||||
if(isAI(user) && (stat & NOPOWER))
|
||||
return
|
||||
var/dat = "<div class='statusDisplay'>"
|
||||
if(broken > 0)
|
||||
dat += "ERROR: 09734014-A2379-D18746 --Bad memory<BR>Contact your operator or use command line to rebase memory ///git checkout {HEAD} -a commit pull --rebase push {*NEW HEAD*}</div>" //Thats how all the git fiddling looks to me
|
||||
else if(operating)
|
||||
dat += "Microwaving in progress!<BR>Please wait...!</div>"
|
||||
else if(dirty==100)
|
||||
dat += "ERROR: >> 0 --Response input zero<BR>Contact your operator of the device manifactor support.</div>"
|
||||
else
|
||||
var/list/items_counts = new
|
||||
for (var/obj/O in contents)
|
||||
if(istype(O, /obj/item/stack/))
|
||||
var/obj/item/stack/S = O
|
||||
items_counts[O.name] += S.amount
|
||||
else
|
||||
items_counts[O.name]++
|
||||
|
||||
for (var/O in items_counts)
|
||||
var/N = items_counts[O]
|
||||
dat += "[capitalize(O)]: [N]<BR>"
|
||||
|
||||
if (items_counts.len==0)
|
||||
dat += "The microwave is empty.</div>"
|
||||
if(!length(ingredients))
|
||||
if(isAI(user))
|
||||
examine(user)
|
||||
else
|
||||
dat = "<h3>Ingredients:</h3>[dat]</div>"
|
||||
dat += "<A href='?src=[REF(src)];action=cook'>Turn on</A>"
|
||||
dat += "<A href='?src=[REF(src)];action=dispose'>Eject ingredients</A><BR>"
|
||||
to_chat(user, "<span class='warning'>\The [src] is empty.</span>")
|
||||
return
|
||||
|
||||
var/datum/browser/popup = new(user, "microwave", name, 300, 300)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
var/choice = show_radial_menu(user, src, isAI(user) ? ai_radial_options : radial_options, require_near = !issilicon(user))
|
||||
|
||||
/***********************************
|
||||
* Microwave Menu Handling/Cooking
|
||||
************************************/
|
||||
// post choice verification
|
||||
if(operating || panel_open || !anchored || !user.canUseTopic(src, !issilicon(user)))
|
||||
return
|
||||
if(isAI(user) && (stat & NOPOWER))
|
||||
return
|
||||
|
||||
usr.set_machine(src)
|
||||
switch(choice)
|
||||
if("eject")
|
||||
eject()
|
||||
if("use")
|
||||
cook()
|
||||
if("examine")
|
||||
examine(user)
|
||||
|
||||
/obj/machinery/microwave/proc/eject()
|
||||
for(var/i in ingredients)
|
||||
var/atom/movable/AM = i
|
||||
AM.forceMove(drop_location())
|
||||
ingredients.Cut()
|
||||
|
||||
/obj/machinery/microwave/proc/cook()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(operating || broken > 0 || panel_open || !anchored || dirty == 100)
|
||||
return
|
||||
|
||||
if(wire_disabled)
|
||||
audible_message("[src] buzzes.")
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
return
|
||||
|
||||
if(prob(max((5 / efficiency) - 5, dirty * 5))) //a clean unupgraded microwave has no risk of failure
|
||||
muck()
|
||||
return
|
||||
for(var/obj/O in ingredients)
|
||||
if(istype(O, /obj/item/reagent_containers/food) || istype(O, /obj/item/grown))
|
||||
continue
|
||||
if(prob(min(dirty * 5, 100)))
|
||||
start_can_fail()
|
||||
return
|
||||
break
|
||||
start()
|
||||
|
||||
if (prob(max(5/efficiency-5,dirty*5))) //a clean unupgraded microwave has no risk of failure
|
||||
muck_start()
|
||||
if (!microwaving(4))
|
||||
muck_finish()
|
||||
return
|
||||
muck_finish()
|
||||
return
|
||||
/obj/machinery/microwave/proc/turn_on()
|
||||
visible_message("\The [src] turns on.", "<span class='italics'>You hear a microwave humming.</span>")
|
||||
operating = TRUE
|
||||
|
||||
else
|
||||
if(has_extra_item() && prob(min(dirty*5,100)) && !microwaving(4))
|
||||
broke()
|
||||
return
|
||||
set_light(1.5)
|
||||
soundloop.start()
|
||||
update_icon()
|
||||
|
||||
if(!microwaving(10))
|
||||
abort()
|
||||
return
|
||||
stop()
|
||||
/obj/machinery/microwave/proc/spark()
|
||||
visible_message("<span class='warning'>Sparks fly around [src]!</span>")
|
||||
var/datum/effect_system/spark_spread/s = new
|
||||
s.set_up(2, 1, src)
|
||||
s.start()
|
||||
|
||||
var/metal = 0
|
||||
for(var/obj/item/O in contents)
|
||||
O.microwave_act(src)
|
||||
if(O.materials[MAT_METAL])
|
||||
metal += O.materials[MAT_METAL]
|
||||
|
||||
if(metal)
|
||||
visible_message("<span class='warning'>Sparks fly around [src]!</span>")
|
||||
if(prob(max(metal/2, 33)))
|
||||
explosion(loc,0,1,2)
|
||||
broke()
|
||||
return
|
||||
|
||||
dropContents()
|
||||
return
|
||||
|
||||
/obj/machinery/microwave/proc/microwaving(seconds as num)
|
||||
for (var/i=1 to seconds)
|
||||
if (stat & (NOPOWER|BROKEN))
|
||||
return 0
|
||||
use_power(500)
|
||||
sleep(max(12-2*efficiency,2)) // standard microwave means sleep(10). The better the efficiency, the faster the cooking
|
||||
return 1
|
||||
|
||||
/obj/machinery/microwave/proc/has_extra_item()
|
||||
for (var/obj/O in contents)
|
||||
if ( \
|
||||
!istype(O, /obj/item/reagent_containers/food) && \
|
||||
!istype(O, /obj/item/grown) \
|
||||
)
|
||||
return 1
|
||||
return 0
|
||||
#define MICROWAVE_NORMAL 0
|
||||
#define MICROWAVE_MUCK 1
|
||||
#define MICROWAVE_PRE 2
|
||||
|
||||
/obj/machinery/microwave/proc/start()
|
||||
visible_message("The microwave turns on.", "<span class='italics'>You hear a microwave humming.</span>")
|
||||
soundloop.start()
|
||||
operating = TRUE
|
||||
icon_state = "mw1"
|
||||
set_light(1.5)
|
||||
updateUsrDialog()
|
||||
turn_on()
|
||||
loop(MICROWAVE_NORMAL, 10)
|
||||
|
||||
/obj/machinery/microwave/proc/abort()
|
||||
operating = FALSE // Turn it off again aferwards
|
||||
icon_state = "mw"
|
||||
updateUsrDialog()
|
||||
set_light(0)
|
||||
soundloop.stop()
|
||||
/obj/machinery/microwave/proc/start_can_fail()
|
||||
turn_on()
|
||||
loop(MICROWAVE_PRE, 4)
|
||||
|
||||
/obj/machinery/microwave/proc/stop()
|
||||
abort()
|
||||
/obj/machinery/microwave/proc/muck()
|
||||
turn_on()
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
dirty_anim_playing = TRUE
|
||||
update_icon()
|
||||
loop(MICROWAVE_MUCK, 4)
|
||||
|
||||
/obj/machinery/microwave/proc/dispose()
|
||||
for (var/obj/O in contents)
|
||||
O.forceMove(drop_location())
|
||||
to_chat(usr, "<span class='notice'>You dispose of the microwave contents.</span>")
|
||||
updateUsrDialog()
|
||||
/obj/machinery/microwave/proc/loop(type, time, wait = max(12 - 2 * efficiency, 2)) // standard wait is 10
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
if(MICROWAVE_PRE)
|
||||
pre_fail()
|
||||
return
|
||||
if(!time)
|
||||
switch(type)
|
||||
if(MICROWAVE_NORMAL)
|
||||
loop_finish()
|
||||
if(MICROWAVE_MUCK)
|
||||
muck_finish()
|
||||
if(MICROWAVE_PRE)
|
||||
pre_success()
|
||||
return
|
||||
time--
|
||||
use_power(500)
|
||||
addtimer(CALLBACK(src, .proc/loop, type, time, wait), wait)
|
||||
|
||||
/obj/machinery/microwave/proc/muck_start()
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) // Play a splat sound
|
||||
icon_state = "mwbloody1" // Make it look dirty!!
|
||||
/obj/machinery/microwave/proc/loop_finish()
|
||||
operating = FALSE
|
||||
|
||||
var/metal = 0
|
||||
for(var/obj/item/O in ingredients)
|
||||
O.microwave_act(src)
|
||||
if(O.materials[MAT_METAL])
|
||||
metal += O.materials[MAT_METAL]
|
||||
|
||||
if(metal)
|
||||
spark()
|
||||
broken = 2
|
||||
if(prob(max(metal / 2, 33)))
|
||||
explosion(loc, 0, 1, 2)
|
||||
else
|
||||
dropContents(ingredients)
|
||||
ingredients.Cut()
|
||||
|
||||
after_finish_loop()
|
||||
|
||||
/obj/machinery/microwave/proc/pre_fail()
|
||||
broken = 2
|
||||
operating = FALSE
|
||||
spark()
|
||||
after_finish_loop()
|
||||
|
||||
/obj/machinery/microwave/proc/pre_success()
|
||||
loop(MICROWAVE_NORMAL, 10)
|
||||
|
||||
/obj/machinery/microwave/proc/muck_finish()
|
||||
visible_message("<span class='warning'>The microwave gets covered in muck!</span>")
|
||||
dirty = 100 // Make it dirty so it can't be used util cleaned
|
||||
icon_state = "mwbloody" // Make it look dirty too
|
||||
operating = FALSE // Turn it off again aferwards
|
||||
updateUsrDialog()
|
||||
visible_message("<span class='warning'>\The [src] gets covered in muck!</span>")
|
||||
|
||||
dirty = 100
|
||||
dirty_anim_playing = FALSE
|
||||
operating = FALSE
|
||||
|
||||
for(var/obj/item/reagent_containers/food/snacks/S in src)
|
||||
if(prob(50))
|
||||
new /obj/item/reagent_containers/food/snacks/badrecipe(src)
|
||||
qdel(S)
|
||||
|
||||
after_finish_loop()
|
||||
|
||||
/obj/machinery/microwave/proc/after_finish_loop()
|
||||
set_light(0)
|
||||
soundloop.stop()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/microwave/proc/broke()
|
||||
var/datum/effect_system/spark_spread/s = new
|
||||
s.set_up(2, 1, src)
|
||||
s.start()
|
||||
icon_state = "mwb" // Make it look all busted up and shit
|
||||
visible_message("<span class='warning'>The microwave breaks!</span>") //Let them know they're stupid
|
||||
broken = 2 // Make it broken so it can't be used util fixed
|
||||
flags_1 = null //So you can't add condiments
|
||||
operating = FALSE // Turn it off again aferwards
|
||||
updateUsrDialog()
|
||||
set_light(0)
|
||||
soundloop.stop()
|
||||
|
||||
/obj/machinery/microwave/Topic(href, href_list)
|
||||
if(..() || panel_open)
|
||||
return
|
||||
|
||||
usr.set_machine(src)
|
||||
if(operating)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
switch(href_list["action"])
|
||||
if ("cook")
|
||||
cook()
|
||||
|
||||
if ("dispose")
|
||||
dispose()
|
||||
updateUsrDialog()
|
||||
#undef MICROWAVE_NORMAL
|
||||
#undef MICROWAVE_MUCK
|
||||
#undef MICROWAVE_PRE
|
||||
@@ -15,6 +15,7 @@
|
||||
var/max_n_of_items = 1500
|
||||
var/allow_ai_retrieve = FALSE
|
||||
var/list/initial_contents
|
||||
var/visible_contents = TRUE
|
||||
|
||||
/obj/machinery/smartfridge/Initialize()
|
||||
. = ..()
|
||||
@@ -37,11 +38,21 @@
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/smartfridge/update_icon()
|
||||
var/startstate = initial(icon_state)
|
||||
if(!stat)
|
||||
icon_state = startstate
|
||||
if(visible_contents)
|
||||
switch(contents.len)
|
||||
if(0)
|
||||
icon_state = "[initial(icon_state)]"
|
||||
if(1 to 25)
|
||||
icon_state = "[initial(icon_state)]1"
|
||||
if(26 to 75)
|
||||
icon_state = "[initial(icon_state)]2"
|
||||
if(76 to INFINITY)
|
||||
icon_state = "[initial(icon_state)]3"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
else
|
||||
icon_state = "[startstate]-off"
|
||||
icon_state = "[initial(icon_state)]-off"
|
||||
|
||||
|
||||
|
||||
@@ -50,7 +61,14 @@
|
||||
********************/
|
||||
|
||||
/obj/machinery/smartfridge/attackby(obj/item/O, mob/user, params)
|
||||
if(default_deconstruction_screwdriver(user, "smartfridge_open", "smartfridge", O))
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
|
||||
if(default_deconstruction_screwdriver(user, icon_state, icon_state, O))
|
||||
cut_overlays()
|
||||
if(panel_open)
|
||||
add_overlay("[initial(icon_state)]-panel")
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if(default_pry_open(O))
|
||||
@@ -64,49 +82,46 @@
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if(!stat)
|
||||
|
||||
if(contents.len >= max_n_of_items)
|
||||
to_chat(user, "<span class='warning'>\The [src] is full!</span>")
|
||||
return FALSE
|
||||
|
||||
if(accept_check(O))
|
||||
load(O)
|
||||
user.visible_message("[user] has added \the [O] to \the [src].", "<span class='notice'>You add \the [O] to \the [src].</span>")
|
||||
updateUsrDialog()
|
||||
return TRUE
|
||||
|
||||
if(istype(O, /obj/item/storage/bag))
|
||||
var/obj/item/storage/P = O
|
||||
var/loaded = 0
|
||||
for(var/obj/G in P.contents)
|
||||
if(contents.len >= max_n_of_items)
|
||||
break
|
||||
if(accept_check(G))
|
||||
load(G)
|
||||
loaded++
|
||||
updateUsrDialog()
|
||||
|
||||
if(loaded)
|
||||
if(contents.len >= max_n_of_items)
|
||||
user.visible_message("[user] loads \the [src] with \the [O].", \
|
||||
"<span class='notice'>You fill \the [src] with \the [O].</span>")
|
||||
else
|
||||
user.visible_message("[user] loads \the [src] with \the [O].", \
|
||||
"<span class='notice'>You load \the [src] with \the [O].</span>")
|
||||
if(O.contents.len > 0)
|
||||
to_chat(user, "<span class='warning'>Some items are refused.</span>")
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There is nothing in [O] to put in [src]!</span>")
|
||||
return FALSE
|
||||
|
||||
if(user.a_intent != INTENT_HARM)
|
||||
to_chat(user, "<span class='warning'>\The [src] smartly refuses [O].</span>")
|
||||
if(stat)
|
||||
updateUsrDialog()
|
||||
return FALSE
|
||||
else
|
||||
return ..()
|
||||
|
||||
if(contents.len >= max_n_of_items)
|
||||
to_chat(user, "<span class='warning'>\The [src] is full!</span>")
|
||||
return FALSE
|
||||
|
||||
if(accept_check(O))
|
||||
load(O)
|
||||
user.visible_message("[user] has added \the [O] to \the [src].", "<span class='notice'>You add \the [O] to \the [src].</span>")
|
||||
updateUsrDialog()
|
||||
if (visible_contents)
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
if(istype(O, /obj/item/storage/bag))
|
||||
var/obj/item/storage/P = O
|
||||
var/loaded = 0
|
||||
for(var/obj/G in P.contents)
|
||||
if(contents.len >= max_n_of_items)
|
||||
break
|
||||
if(accept_check(G))
|
||||
load(G)
|
||||
loaded++
|
||||
updateUsrDialog()
|
||||
|
||||
if(loaded)
|
||||
user.visible_message("[user] loads \the [src] with \the [O].", \
|
||||
"<span class='notice'>You [contents.len >= max_n_of_items ? "fill" : "load"] \the [src] with \the [O].</span>")
|
||||
if(O.contents.len > 0)
|
||||
to_chat(user, "<span class='warning'>Some items are refused.</span>")
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There is nothing in [O] to put in [src]!</span>")
|
||||
return FALSE
|
||||
|
||||
to_chat(user, "<span class='warning'>\The [src] smartly refuses [O].</span>")
|
||||
updateUsrDialog()
|
||||
return FALSE
|
||||
|
||||
|
||||
|
||||
@@ -186,6 +201,8 @@
|
||||
O.forceMove(drop_location())
|
||||
adjust_item_drop_location(O)
|
||||
break
|
||||
if (visible_contents)
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
for(var/obj/item/O in src)
|
||||
@@ -195,6 +212,8 @@
|
||||
O.forceMove(drop_location())
|
||||
adjust_item_drop_location(O)
|
||||
desired--
|
||||
if (visible_contents)
|
||||
update_icon()
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -210,6 +229,7 @@
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 200
|
||||
visible_contents = FALSE
|
||||
var/drying = FALSE
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/Initialize()
|
||||
@@ -414,6 +434,7 @@
|
||||
name = "disk compartmentalizer"
|
||||
desc = "A machine capable of storing a variety of disks. Denoted by most as the DSU (disk storage unit)."
|
||||
icon_state = "disktoaster"
|
||||
visible_contents = FALSE
|
||||
pass_flags = PASSTABLE
|
||||
|
||||
/obj/machinery/smartfridge/disks/accept_check(obj/item/O)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user