diff --git a/code/WorkInProgress/Chemistry-Machinery.dm b/code/WorkInProgress/Chemistry-Machinery.dm index 299ea2dfb1..4dabde5358 100644 --- a/code/WorkInProgress/Chemistry-Machinery.dm +++ b/code/WorkInProgress/Chemistry-Machinery.dm @@ -297,7 +297,7 @@ var/type = text2path(href_list["create_virus_culture"])//the path is received as string - converting var/datum/disease/D = new type var/list/data = list("virus"=D) - var/name = input(usr,"Name:","Name the culture",D.name) + var/name = sanitize(input(usr,"Name:","Name the culture",D.name)) if(!name || name == " ") name = D.name B.name = "[name] culture bottle" B.desc = "A small bottle. Contains [D.agent] culture in synthblood medium." diff --git a/code/datums/disease.dm b/code/datums/disease.dm index 19dae7fb85..9e9f6b9ec6 100644 --- a/code/datums/disease.dm +++ b/code/datums/disease.dm @@ -268,7 +268,7 @@ to null does not delete the object itself. Thank you. var/check_range = AIRBORNE//defaults to airborne - range 4 if(src.spread_type != AIRBORNE) - check_range = 1 + check_range = 0 for(var/mob/living/carbon/M in oviewers(check_range, source)) M.contract_disease(src) diff --git a/code/defines/global.dm b/code/defines/global.dm index e1d4bbe24c..e8577c989d 100644 --- a/code/defines/global.dm +++ b/code/defines/global.dm @@ -17,6 +17,17 @@ var/global powerreportavail = null powerreportviewload = null + list/global_map = null + //list/global_map = list(list(1,5),list(4,3))//an array of map Z levels. + //Resulting sector map looks like + //|_1_|_4_| + //|_5_|_3_| + // + //1 - SS13 + //4 - Derelict + //3 - AI satellite + //5 - empty space + var ////////////// diff --git a/code/game/asteroid/asteroid.dm b/code/game/asteroid/asteroid.dm new file mode 100644 index 0000000000..2430f49eb7 --- /dev/null +++ b/code/game/asteroid/asteroid.dm @@ -0,0 +1,116 @@ +proc/spawn_asteroid(var/atom/start_loc,var/type,var/size)//type: 0 or null - random, 1 - nothing, 2 - iron, 3 - silicon + if(!size) + size = pick(100;2,50;3,35;4,25;6,10;12) + if(!type) + type = pick(50;1,2,3) +// world << "Asteroid size: [size]; Asteroid type: [type]" + if(start_loc.x - size < 3 || start_loc.x + size >= world.maxx - 3 || start_loc.y - size < 3 || start_loc.y + size > world.maxy -3) + return 0 + var/list/turfs = circlerange(start_loc,size) + for(var/turf/T in turfs) + var/dist = get_dist(start_loc,T) + if(prob(100-(dist*rand(2,4))))//I'm terrible at generating random things. + var/turf/simulated/wall/asteroid/A + if(type > 1 && prob(25)) + switch(type) + if(2) + A = new /turf/simulated/wall/asteroid/iron(T) + if(3) + A = new /turf/simulated/wall/asteroid/silicon(T) + else + A = new /turf/simulated/wall/asteroid(T) + A.opacity = 0 + A.sd_NewOpacity(1) +/* + if(max_secret_rooms && size == 12) + var/x_len = rand(4,12) + var/y_len = pick(4,12) + var/st_l = locate(start_loc.x-round(x_len/2),start_loc.y-round(y_len/2),start_loc.z) + spawn_room(st_l,x_len,y_len) + max_secret_rooms-- +*/ + return 1 + +/proc/populate_w_asteroids(var/z,var/density) + if(!density) + density = pick(10,20,40) + while(density) + var/x = rand(1,world.maxx) + var/y = rand(1,world.maxy) +// world << "Asteroid coords: [x], [y], [z]" + var/start_loc = locate(x,y,z) + if(spawn_asteroid(start_loc)) + density-- + return + + +/datum/game_mode/proc/setup_sectors() + world << "\blue \b Randomizing space sectors." + var/list/sectors = list(1,3,4,0,0,0,0,0,0) + var/length = sectors.len/3 + global_map = new/list(length,length)//3x3 map + var/x + var/y + + for(x=1,x<=length,x++) + for(y=1,y<=length,y++) + var/sector + if(sectors.len) + sector = pick(sectors) + sectors -= sector + if(sector == 0) + sector = ++world.maxz + populate_w_asteroids(sector) + global_map[x][y] = sector + else + break + world << "\blue \b Randomization complete." +/* + //debug + for(x=1,x<=global_map.len,x++) + var/list/y_arr = global_map[x] + for(y=1,y<=y_arr.len,y++) + var/t = "" + switch(y_arr[y]) + if(1) t = "SS13" + if(3) t = "AI Satellite" + if(4) t = "Derelict" + else t = "Empty Cold Space" + world << "Global map [x] - [y] contains [t] (Z = [y_arr[y]])" + //debug +*/ + return + +/datum/game_mode/proc/spawn_exporation_packs() + for (var/obj/landmark/L in world) + if (L.tag == "landmark*ExplorationPack") + new /obj/item/weapon/storage/explorers_box(L.loc) + del(L) + return + + +proc/spawn_room(var/atom/start_loc,var/x_size,var/y_size,var/wall,var/floor) + var/list/room_turfs = list("walls"=list(),"floors"=list()) + + world << "Room spawned at [start_loc.x],[start_loc.y],[start_loc.z]" + if(!wall) + wall = pick(/turf/simulated/wall/r_wall,/turf/simulated/wall) + if(!floor) + floor = pick(/turf/simulated/floor,/turf/simulated/floor/engine) + + for(var/x = 0,xsrc_global_loc["x"]) + hor_dir = EAST + else if(beacon_global_loc["x"]src_global_loc["y"]) + ver_dir = NORTH + else if(beacon_global_loc["y"]The current game mode is - Extended Role-Playing!" world << "Just have fun and role-play!" +/datum/game_mode/extended/pre_setup() + setup_sectors() + spawn_exporation_packs() + return 1 + diff --git a/code/game/gamemodes/sandbox/sandbox.dm b/code/game/gamemodes/sandbox/sandbox.dm index fe2733f94c..01fcfa0593 100644 --- a/code/game/gamemodes/sandbox/sandbox.dm +++ b/code/game/gamemodes/sandbox/sandbox.dm @@ -11,6 +11,8 @@ if(M.client && M.client.authenticated) M.CanBuild() + setup_sectors() + spawn_exporation_packs() return 1 /datum/game_mode/sandbox/check_finished() diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index bbeb90751a..410d9f1923 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -14,12 +14,12 @@ req_access = list(access_atmospherics) attack_hand(mob/user) - if(!(istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/carbon/human))) + if(!(istype(usr, /mob/living/silicon) || istype(usr, /mob/living/carbon/human))) user << "\red You don't have the dexterity to do this" return if(stat & (NOPOWER|BROKEN)) return - else if(!(istype(usr, /mob/living/silicon/ai)) && locked) + else if(!(istype(usr, /mob/living/silicon)) && locked) user << "\red You must unlock the Air Alarm interface first" return src.add_fingerprint(user) diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm new file mode 100644 index 0000000000..c300ff9f0a --- /dev/null +++ b/code/game/mecha/combat/combat.dm @@ -0,0 +1,157 @@ +/obj/mecha/combat + deflect_chance = 20 + health = 500 + + var/weapon_1 = null + var/weapon_1_cooldown = 0 + var/weapon_1_ready = 1 + var/weapon_1_name = "some weapon" + var/weapon_1_energy_drain = 0 + var/weapon_2 = null + var/weapon_2_cooldown = 0 + var/weapon_2_ready = 1 + var/weapon_2_name = "another weapon" + var/weapon_2_energy_drain = 0 + var/selected_weapon = 1 + var/overload = 0 + var/melee_damage = 20 + req_access = access_heads + +/obj/mecha/combat/verb/switch_weapon() + set category = "Exosuit Interface" + set name = "Switch weapon" + set src in view(0) + if(state || !cell || cell.charge<=0) return + if(usr!=src.occupant) + return + if(selected_weapon == 1) + selected_weapon = 2 + src.occupant << "You switch to [weapon_2_name]" + for (var/mob/M in oviewers(src)) + M.show_message("[src.name] raises [weapon_2_name]") + else if(selected_weapon == 2) + selected_weapon = 1 + src.occupant << "You switch to [weapon_1_name]" + for (var/mob/M in oviewers(src)) + M.show_message("[src.name] raises [weapon_1_name]") + return + +/obj/mecha/combat/verb/overload() + set category = "Exosuit Interface" + set name = "Toggle leg actuators overload" + set src in view(0) + if(overload) + overload = 0 + step_in = initial(step_in) + src.occupant << "\blue You disable leg actuators overload." + else + overload = 1 + step_in = min(1, round(step_in/2)) + src.occupant << "\red You enable leg actuators overload." + + +/obj/mecha/combat/click_action(target) + if(state || !cell || cell.charge<=0) return + if(get_dist(src,target)<=1) + src.mega_punch(target) + +/* + if(src.occupant.a_intent == "hurt") + src.mega_punch(target) + else if(src.occupant.a_intent == "help") + src.mega_shake(target) +*/ + else + src.fire(src.selected_weapon,target) + return + + +/obj/mecha/combat/proc/fire(weapon_num,target) + var/turf/curloc = src.loc + var/atom/targloc = get_turf(target) + if (!targloc || !istype(targloc, /turf) || !curloc) + return + var/weapon_type + switch(weapon_num) + if(1) + if(weapon_1_ready) + weapon_type = weapon_1 + weapon_1_ready = 0 + spawn(weapon_1_cooldown) + cell.use(weapon_1_energy_drain) + weapon_1_ready = 1 + if(2) + if(weapon_2_ready) + weapon_type = weapon_2 + weapon_2_ready = 0 + spawn(weapon_2_cooldown) + cell.use(weapon_2_energy_drain) + weapon_2_ready = 1 + + + if(!weapon_type) return + + + playsound(src, 'Laser.ogg', 50, 1) + if (targloc == curloc) + src.bullet_act(PROJECTILE_PULSE) + return + + var/obj/beam/a_laser/A = new weapon_type(src.loc) + A.current = curloc + A.yo = targloc.y - curloc.y + A.xo = targloc.x - curloc.x + spawn() + A.process() + + return + +/obj/mecha/combat/proc/mega_punch(target) + if(!istype(target, /obj) && !istype(target, /mob)) return + if(istype(target, /mob)) + var/mob/M = target + M.bruteloss += rand(melee_damage/2, melee_damage) + M.paralysis += 1 + M.updatehealth() + step_away(M,src,15) + for (var/mob/V in viewers(src)) + V.show_message("[src.name] sends [M] flying.") + return + +/* +/obj/mecha/combat/proc/mega_shake(target) + if(!istype(target, /obj) && !istype(target, /mob)) return + if(istype(target, /mob)) + var/mob/M = target + M.make_dizzy(3) + M.bruteloss += 1 + M.updatehealth() + for (var/mob/V in viewers(src)) + V.show_message("[src.name] shakes [M] like a rag doll.") + return +*/ + +/obj/mecha/combat/relaymove(mob/user,direction) + if(!..()) return + if(overload) + cell.use(step_energy_drain) + health-- + if(health < initial(health) - initial(health)/3) + overload = 0 + src.occupant << "\red Leg actuators damage treshold exceded. Disabling overload." + + +/* + if(energy>0 && can_move) + if(step(src,direction)) + can_move = 0 + spawn(step_in) can_move = 1 + if(overload) + energy = energy-2 + health-- + else + energy-- + return 1 + + return 0 +*/ \ No newline at end of file diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm new file mode 100644 index 0000000000..1c796a6380 --- /dev/null +++ b/code/game/mecha/combat/gygax.dm @@ -0,0 +1,14 @@ +/obj/mecha/combat/gygax + desc = "Heavy duty combat exosuit." + name = "Gygax" + icon_state = "gygax" + step_in = 8 + + weapon_1 = /obj/beam/a_laser/pulse_laser + weapon_1_cooldown = 50 + weapon_1_name = "eZ-13 mk2 Heavy pulse rifle" + weapon_1_energy_drain = 50 + weapon_2 = /obj/beam/a_laser + weapon_2_cooldown = 10 + weapon_2_name = "CH-PS \"Immolator\" Laser" + weapon_2_energy_drain = 20 diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm new file mode 100644 index 0000000000..827750f80b --- /dev/null +++ b/code/game/mecha/mecha.dm @@ -0,0 +1,388 @@ +/obj/mecha + name = "Mecha" + icon = 'mecha.dmi' + density = 1 //Dense. To raise the heat. + opacity = 1 ///opaque. Menacing. + anchored = 1 //no pulling around. + var/can_move = 1 + var/mob/living/carbon/human/occupant = null + var/step_in = 10 //make a step in step_in/10 sec. + var/step_energy_drain = 10 + var/health = 300 //health is health + var/deflect_chance = 5 //chance to deflect the incoming projectiles, or lesser the effect of ex_act. + var/obj/item/weapon/cell/cell = new + var/state = 0 + + + var/datum/effects/system/spark_spread/spark_system = new + var/lights = 0 + var/lights_power = 6 + var/inertia_dir = null //for open space travel. + + //inner atmos machinery. Air tank mostly + var/datum/gas_mixture/air_contents = new + var/obj/machinery/atmospherics/portables_connector/connected_port = null //filling the air tanks + var/filled = 0.5 + var/gas_tank_volume = 80 + var/maximum_pressure = 30*ONE_ATMOSPHERE + + req_access = access_engine + var/operating_access = null + +/obj/mecha/New() + ..() + src.air_contents.volume = gas_tank_volume //liters + src.air_contents.temperature = T20C + src.air_contents.oxygen = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) + src.spark_system.set_up(5, 0, src) + src.spark_system.attach(src) + src.cell.charge = 15000 + src.cell.maxcharge = 15000 + preserve_temp() + src.verbs -= /obj/mecha/verb/disconnect_from_port + + +/client/Click(object,location,control,params) + ..() + var/mob/M = src.mob + if(M && istype(M.loc, /obj/mecha)) + if(M.stat>0) return + if(!istype(object,/atom)) return + var/obj/mecha/Mech = M.loc + Mech.click_action(object) + + +/obj/mecha/proc/click_action(target) + return + + + +////////////////////////////////// +//////// Movement procs //////// +////////////////////////////////// + +/obj/mecha/relaymove(mob/user,direction) + if(connected_port) + src.occupant << "Unable to move while connected to the air system port" + return 0 + if(src.inertia_dir) + return 0 + if(state || !cell || cell.charge<=0) return 0 + if(can_move) + if(istype(src.loc, /turf/space)) + var/new_pos = get_step(src,direction) +/* world << "Next pos = [new_pos]" + + var/turf = locate(new_pos) + world << "Turf is [turf]"*/ + if(istype(new_pos, /turf/space)) + if(!src.check_for_support()) + src.inertia_dir = direction + src.inertial_movement() + return 0 + if(step(src,direction)) + can_move = 0 + spawn(step_in) can_move = 1 + cell.use(src.step_energy_drain) + return 1 + return 0 + +/obj/mecha/proc/inertial_movement() + if(check_for_support()) + src.inertia_dir = null + if(src.inertia_dir) + step(src, src.inertia_dir) + spawn(5) + .() + return + +/obj/mecha/proc/check_for_support() + if(locate(/obj/grille, orange(1, src)) || locate(/obj/lattice, orange(1, src)) || locate(/turf/simulated, orange(1, src)) || locate(/turf/unsimulated, orange(1, src))) + return 1 + else + return 0 + +/obj/mecha/Bump(var/atom/obstacle) + src.inertia_dir = null + if(src.occupant) + if(istype(obstacle , /obj/machinery/door)) + var/obj/machinery/door/D = obstacle + D.Bumped(src.occupant) + return + else + obstacle.Bumped(src) + return + + +//////////////////////////////////////// +//////// Health related procs //////// +//////////////////////////////////////// + +/obj/mecha/bullet_act(flag) + if(prob(src.deflect_chance)) + if(src.occupant && src.occupant.client) + src.occupant << "\blue The armor deflects the incoming projectile." + return + else + switch(flag) + if(PROJECTILE_PULSE) + src.health -= 40 + if(PROJECTILE_LASER) + src.health -= 20 + else + src.health -= 10 + if(src.health > 0) + src.spark_system.start() + else + src.destroy() + +/obj/mecha/proc/destroy() + if(src.occupant) + var/mob/M = src.occupant + src.go_out() + if(prob(20)) + M.bruteloss += rand(10,20) + M.updatehealth() + else + M.gib() + explosion(src.loc, 1, 0, 2, 4) + spawn() + del(src) + return + +/obj/mecha/ex_act(severity) + if(prob(src.deflect_chance)) + severity++ + switch(severity) + if(1.0) + destroy(src) + return + if(2.0) + if (prob(30)) + destroy(src) + else + src.health = src.health/2 + src.spark_system.start() + return + if(3.0) + if (prob(5)) + destroy(src) + else + src.health = src.health - src.health/4 + src.spark_system.start() + return + + +///////////////////////////////////// +//////// Atmospheric stuff //////// +///////////////////////////////////// + +/* //standard for /obj class +/obj/mecha/handle_internal_lifeform(lifeform, volume) + ..() + world << "Handling occupant breathing" +*/ + +/obj/mecha/remove_air(amount) + return src.air_contents.remove(amount) + +/obj/mecha/return_air() + return src.air_contents + +/obj/mecha/proc/return_pressure() + return src.air_contents.return_pressure() + +/obj/mecha/proc/preserve_temp() + if(!cell || cell.charge<=0) return + if(src.occupant) + if(src.occupant.bodytemperature > 320 || src.occupant.bodytemperature < 300) + src.occupant.bodytemperature += src.occupant.adjust_body_temperature(src.occupant.bodytemperature, 310.15, 10) + cell.charge-- + spawn(10) + .() + +/obj/mecha/proc/connect(obj/machinery/atmospherics/portables_connector/new_port) + //Make sure not already connected to something else + if(src.connected_port || !new_port || new_port.connected_device) + return 0 + + //Make sure are close enough for a valid connection + if(new_port.loc != src.loc) + return 0 + + //Perform the connection + src.connected_port = new_port + src.connected_port.connected_device = src + + //Actually enforce the air sharing + var/datum/pipe_network/network = connected_port.return_network(src) + if(network && !network.gases.Find(air_contents)) + network.gases += air_contents + + return 1 + +/obj/mecha/proc/disconnect() + if(!connected_port) + return 0 + + var/datum/pipe_network/network = connected_port.return_network(src) + if(network) + network.gases -= air_contents + + connected_port.connected_device = null + connected_port = null + + return 1 + + +///////////////////////// +//////// Verbs //////// +///////////////////////// + +/obj/mecha/verb/connect_to_port() + set name = "Connect to port" + set category = "Exosuit Interface" + set src in view(0) + if(!src.occupant) return + var/obj/machinery/atmospherics/portables_connector/possible_port = locate(/obj/machinery/atmospherics/portables_connector/) in loc + if(possible_port) + if(connect(possible_port)) + src.occupant << "\blue [name] connects to the port." + src.verbs += /obj/mecha/verb/disconnect_from_port + src.verbs -= /obj/mecha/verb/connect_to_port + return + else + src.occupant << "\red [name] failed to connect to the port." + return + else + src.occupant << "Nothing happens" + + +/obj/mecha/verb/disconnect_from_port() + set name = "Disconnect from port" + set category = "Exosuit Interface" + set src in view(0) + if(!src.occupant) return + if(disconnect()) + src.occupant << "\blue [name] disconnects from the port." + src.verbs -= /obj/mecha/verb/disconnect_from_port + src.verbs += /obj/mecha/verb/connect_to_port + else + src.occupant << "\red [name] is not connected to the port at the moment." + + +/obj/mecha/verb/toggle_lights() + set name = "Toggle Lights" + set category = "Exosuit Interface" + set src in view(0) + lights = !lights + if(lights) + src.sd_SetLuminosity(src.luminosity + src.lights_power) + else + src.sd_SetLuminosity(src.luminosity - src.lights_power) + +/obj/mecha/verb/move_inside() + set name = "Move Inside" + set src in oview(1) + + if (usr.stat != 0 || !istype(usr, /mob/living/carbon/human)) + return + if (src.occupant) + usr << "\blue The [src.name] is already occupied!" + return +/* + if (usr.abiotic()) + usr << "\blue Subject cannot have abiotic items on." + return +*/ + usr << "You start climbing into [src.name]" + spawn(20) + if(usr in range(1)) + usr.pulling = null + // usr.client.eye = src + usr.loc = src + src.occupant = usr + src.add_fingerprint(usr) + return + +/obj/mecha/verb/eject() + set name = "Eject" + set category = "Exosuit Interface" + set src in view(0) + if(usr!=src.occupant) + return + src.go_out() + add_fingerprint(usr) + return + + +/obj/mecha/proc/go_out() + if(!src.occupant) return + if (src.occupant.client) + src.occupant.client.eye = src.occupant.client.mob + src.occupant.client.perspective = MOB_PERSPECTIVE + src.occupant.loc = src.loc + src.occupant = null + return + +////// Misc + +/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/card/id)) + if(src.allowed(usr)) + if(state==0) + state = 1 + user << "The securing bolts are now exposed." + else if(state==1) + state = 0 + user << "The securing bolts are now hidden." + else + user << "\red Access denied." + return + + else if(istype(W, /obj/item/weapon/wrench)) + if(state==1) + state = 2 + user << "You undo the securing bolts." + else if(state==2) + state = 1 + user << "You tighten the securing bolts." + return + + else if(istype(W, /obj/item/weapon/crowbar)) + if(state==2) + state = 3 + user << "You open the hatch to the power unit" + else if(state==3) + state=2 + user << "You close the hatch to the power unit" + return + + else if(istype(W, /obj/item/weapon/screwdriver)) + if(state==3 && src.cell) + src.cell.loc = src.loc + src.cell = null + state = 4 + user << "You unscrew and pry out the powercell." + else if(state==4 && src.cell) + state=3 + user << "You screw the cell in place" + return + + else if(istype(W, /obj/item/weapon/cell)) + if(state==4) + if(!src.cell) + user << "You install the powercell" + user.drop_item() + W.loc = src + src.cell = W + else + user << "There's already a powercell installed." + return + + + ..() + return + + + diff --git a/code/game/turf.dm b/code/game/turf.dm index 5054622b0b..c7dc6dc914 100644 --- a/code/game/turf.dm +++ b/code/game/turf.dm @@ -780,178 +780,293 @@ turf/simulated/floor/proc/update_icon() else M.inertia_dir = M.last_move step(M, M.inertia_dir) //TODO: DEFERRED - if(ticker && ticker.mode && ticker.mode.name == "nuclear emergency") - return - if (src.x <= 2) - if(prob(50)) - if(istype(A, /obj/meteor)) - del(A) - return - if(istype(A,/mob/living/carbon/human)) - if(A:knowledge) - if(A:knowledge > 0) - if(prob(50)) - A.z = 8 - else - A.z = 3 - else - A.z = 3 - else - A.z = 3 - else - A.z = 3 - A.x = world.maxx - 2 - spawn (0) - if ((A && A.loc)) - A.loc.Entered(A) - else - if(istype(A, /obj/meteor)) - del(A) - return - if(istype(A,/mob/living/carbon/human)) - if(A:knowledge) - if(A:knowledge > 0) - if(prob(50)) - A.z = 8 - else - A.z = 4 - else - A.z = 4 - else - A.z = 4 - else - A.z = 4 - A.x = world.maxx - 2 - spawn (0) - if ((A && A.loc)) - A.loc.Entered(A) - else if (A.x >= (world.maxx - 1)) - if(prob(50)) - if(istype(A, /obj/meteor)) - del(A) - return - if(istype(A,/mob/living/carbon/human)) - if(A:knowledge) - if(A:knowledge > 0) - if(prob(50)) - A.z = 8 - else - A.z = 3 - else - A.z = 3 - else - A.z = 3 - else - A.z = 3 - A.x = 3 - spawn (0) - if ((A && A.loc)) - A.loc.Entered(A) - else - if(istype(A, /obj/meteor)) - del(A) - return - if(istype(A,/mob/living/carbon/human)) - if(A:knowledge) - if(A:knowledge > 0) - if(prob(50)) - A.z = 8 - else - A.z = 4 - else - A.z = 4 - else - A.z = 4 - else - A.z = 4 - A.x = 3 - spawn (0) - if ((A && A.loc)) - A.loc.Entered(A) - else if (src.y <= 2) - if(prob(50)) - if(istype(A, /obj/meteor)) - del(A) - return - if(istype(A,/mob/living/carbon/human)) - if(A:knowledge) - if(A:knowledge > 0) - if(prob(50)) - A.z = 8 - else - A.z = 3 - else - A.z = 3 - else - A.z = 3 - else - A.z = 3 - A.y = world.maxy - 2 - spawn (0) - if ((A && A.loc)) - A.loc.Entered(A) - else - if(istype(A, /obj/meteor)) - del(A) - return - if(istype(A,/mob/living/carbon/human)) - if(A:knowledge > 0) - if(A:knowledge > 0) - if(prob(50)) - A.z = 8 - else - A.z = 4 - else - A.z = 4 - else - A.z = 4 - else - A.z = 4 - A.y = world.maxy - 2 - spawn (0) - if ((A && A.loc)) - A.loc.Entered(A) + if(ticker && ticker.mode) + if(ticker.mode.name == "nuclear emergency") + return + + else if(ticker.mode.name == "extended"||ticker.mode.name == "sandbox") + + var/cur_x + var/cur_y + var/next_x + var/next_y + var/target_z + var/list/y_arr + + if(src.x <= 1) + if(istype(A, /obj/meteor)) + del(A) + return + + var/list/cur_pos = src.get_global_map_pos() + if(!cur_pos) return + cur_x = cur_pos["x"] + cur_y = cur_pos["y"] + next_x = (--cur_x||global_map.len) + y_arr = global_map[next_x] + target_z = y_arr[cur_y] +/* + //debug + world << "Src.z = [src.z] in global map X = [cur_x], Y = [cur_y]" + world << "Target Z = [target_z]" + world << "Next X = [next_x]" + //debug +*/ + if(target_z) + A.z = target_z + A.x = world.maxx - 2 + spawn (0) + if ((A && A.loc)) + A.loc.Entered(A) + else if (src.x >= world.maxx) + if(istype(A, /obj/meteor)) + del(A) + return + + var/list/cur_pos = src.get_global_map_pos() + if(!cur_pos) return + cur_x = cur_pos["x"] + cur_y = cur_pos["y"] + next_x = (++cur_x > global_map.len ? 1 : cur_x) + y_arr = global_map[next_x] + target_z = y_arr[cur_y] +/* + //debug + world << "Src.z = [src.z] in global map X = [cur_x], Y = [cur_y]" + world << "Target Z = [target_z]" + world << "Next X = [next_x]" + //debug +*/ + if(target_z) + A.z = target_z + A.x = 3 + spawn (0) + if ((A && A.loc)) + A.loc.Entered(A) + else if (src.y <= 1) + if(istype(A, /obj/meteor)) + del(A) + return + var/list/cur_pos = src.get_global_map_pos() + if(!cur_pos) return + cur_x = cur_pos["x"] + cur_y = cur_pos["y"] + y_arr = global_map[cur_x] + next_y = (--cur_y||y_arr.len) + target_z = y_arr[next_y] +/* + //debug + world << "Src.z = [src.z] in global map X = [cur_x], Y = [cur_y]" + world << "Next Y = [next_y]" + world << "Target Z = [target_z]" + //debug +*/ + if(target_z) + A.z = target_z + A.y = world.maxy - 2 + spawn (0) + if ((A && A.loc)) + A.loc.Entered(A) + + else if (src.y >= world.maxy) + if(istype(A, /obj/meteor)) + del(A) + return + var/list/cur_pos = src.get_global_map_pos() + if(!cur_pos) return + cur_x = cur_pos["x"] + cur_y = cur_pos["y"] + y_arr = global_map[cur_x] + next_y = (++cur_y > y_arr.len ? 1 : cur_y) + target_z = y_arr[next_y] +/* + //debug + world << "Src.z = [src.z] in global map X = [cur_x], Y = [cur_y]" + world << "Next Y = [next_y]" + world << "Target Z = [target_z]" + //debug +*/ + if(target_z) + A.z = target_z + A.y = 3 + spawn (0) + if ((A && A.loc)) + A.loc.Entered(A) + return + - else if (A.y >= (world.maxy - 1)) - if(prob(50)) - if(istype(A, /obj/meteor)) - del(A) - return - if(istype(A,/mob/living/carbon/human)) - if(A:knowledge) - if(A:knowledge > 0) - if(prob(50)) - A.z = 8 - else - A.z = 3 - else - A.z = 3 - else - A.z = 3 - else - A.z = 3 - A.y = 3 - spawn (0) - if ((A && A.loc)) - A.loc.Entered(A) else - if(istype(A, /obj/meteor)) - del(A) - return - if(istype(A,/mob/living/carbon/human)) - if(A:knowledge) - if(A:knowledge > 0) - if(prob(50)) - A.z = 8 + + if (src.x <= 2) + if(prob(50)) + if(istype(A, /obj/meteor)) + del(A) + return + if(istype(A,/mob/living/carbon/human)) + if(A:knowledge) + if(A:knowledge > 0) + if(prob(50)) + A.z = 8 + else + A.z = 3 + else + A.z = 3 else A.z = 3 else A.z = 3 + A.x = world.maxx - 2 + spawn (0) + if ((A && A.loc)) + A.loc.Entered(A) else - A.z = 3 - else - A.z = 3 - A.y = 3 - spawn (0) - if ((A && A.loc)) - A.loc.Entered(A) + if(istype(A, /obj/meteor)) + del(A) + return + if(istype(A,/mob/living/carbon/human)) + if(A:knowledge) + if(A:knowledge > 0) + if(prob(50)) + A.z = 8 + else + A.z = 4 + else + A.z = 4 + else + A.z = 4 + else + A.z = 4 + A.x = world.maxx - 2 + spawn (0) + if ((A && A.loc)) + A.loc.Entered(A) + else if (A.x >= (world.maxx - 1)) + if(prob(50)) + if(istype(A, /obj/meteor)) + del(A) + return + if(istype(A,/mob/living/carbon/human)) + if(A:knowledge) + if(A:knowledge > 0) + if(prob(50)) + A.z = 8 + else + A.z = 3 + else + A.z = 3 + else + A.z = 3 + else + A.z = 3 + A.x = 3 + spawn (0) + if ((A && A.loc)) + A.loc.Entered(A) + else + if(istype(A, /obj/meteor)) + del(A) + return + if(istype(A,/mob/living/carbon/human)) + if(A:knowledge) + if(A:knowledge > 0) + if(prob(50)) + A.z = 8 + else + A.z = 4 + else + A.z = 4 + else + A.z = 4 + else + A.z = 4 + A.x = 3 + spawn (0) + if ((A && A.loc)) + A.loc.Entered(A) + else if (src.y <= 2) + if(prob(50)) + if(istype(A, /obj/meteor)) + del(A) + return + if(istype(A,/mob/living/carbon/human)) + if(A:knowledge) + if(A:knowledge > 0) + if(prob(50)) + A.z = 8 + else + A.z = 3 + else + A.z = 3 + else + A.z = 3 + else + A.z = 3 + A.y = world.maxy - 2 + spawn (0) + if ((A && A.loc)) + A.loc.Entered(A) + else + if(istype(A, /obj/meteor)) + del(A) + return + if(istype(A,/mob/living/carbon/human)) + if(A:knowledge > 0) + if(A:knowledge > 0) + if(prob(50)) + A.z = 8 + else + A.z = 4 + else + A.z = 4 + else + A.z = 4 + else + A.z = 4 + A.y = world.maxy - 2 + spawn (0) + if ((A && A.loc)) + A.loc.Entered(A) + + else if (A.y >= (world.maxy - 1)) + if(prob(50)) + if(istype(A, /obj/meteor)) + del(A) + return + if(istype(A,/mob/living/carbon/human)) + if(A:knowledge) + if(A:knowledge > 0) + if(prob(50)) + A.z = 8 + else + A.z = 3 + else + A.z = 3 + else + A.z = 3 + else + A.z = 3 + A.y = 3 + spawn (0) + if ((A && A.loc)) + A.loc.Entered(A) + else + if(istype(A, /obj/meteor)) + del(A) + return + if(istype(A,/mob/living/carbon/human)) + if(A:knowledge) + if(A:knowledge > 0) + if(prob(50)) + A.z = 8 + else + A.z = 3 + else + A.z = 3 + else + A.z = 3 + else + A.z = 3 + A.y = 3 + spawn (0) + if ((A && A.loc)) + A.loc.Entered(A) diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 144358d3f7..94bc7cac56 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -600,6 +600,7 @@ to clean it up, or just beat the shit out of it (which takes ages). return /mob/living/carbon/alien/humanoid/attack_paw(mob/M as mob) + ..() if (M.a_intent == "help") src.sleeping = 0 src.resting = 0 @@ -628,6 +629,8 @@ to clean it up, or just beat the shit out of it (which takes ages). M << "No attacking people at spawn, you jackass." return + ..() + if ((M.gloves && M.gloves.elecgen == 1 && M.a_intent == "hurt") /*&& (!istype(src:wear_suit, /obj/item/clothing/suit/judgerobe))*/) if(M.gloves.uses > 0) M.gloves.uses-- diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 2b837fed30..c841862171 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -29,7 +29,7 @@ if(M.client) M.show_message(text("\red [user] attacks [src]'s stomach wall with the [I.name]!"), 2) playsound(user.loc, 'attackblob.ogg', 50, 1) - + if(prob(src.bruteloss - 50)) src.gib() @@ -41,4 +41,40 @@ for(var/mob/N in viewers(src, null)) if(N.client) N.show_message(text("\red [M] bursts out of [src]!"), 2) - . = ..(give_medal) \ No newline at end of file + . = ..(give_medal) + + +/mob/living/carbon/attack_hand(mob/M as mob) + if(!istype(M, /mob/living/carbon)) return + if(src.virus || M.virus) + var/s_spread_type + if(src.virus && src.virus.spread_type!=SPECIAL && src.virus.spread_type!=AIRBORNE) + s_spread_type = src.virus.spread_type + src.virus.spread_type = CONTACT_HANDS + M.contract_disease(src.virus) + src.virus.spread_type = s_spread_type + + if(M.virus && M.virus.spread_type!=SPECIAL && M.virus.spread_type!=AIRBORNE) + s_spread_type = M.virus.spread_type + M.virus.spread_type = CONTACT_GENERAL + src.contract_disease(M.virus) + M.virus.spread_type = s_spread_type + return + + +/mob/living/carbon/attack_paw(mob/M as mob) + if(!istype(M, /mob/living/carbon)) return + if(src.virus || M.virus) + var/s_spread_type + if(src.virus && src.virus.spread_type!=SPECIAL && src.virus.spread_type!=AIRBORNE) + s_spread_type = src.virus.spread_type + src.virus.spread_type = CONTACT_HANDS + M.contract_disease(src.virus) + src.virus.spread_type = s_spread_type + + if(M.virus && M.virus.spread_type!=SPECIAL && M.virus.spread_type!=AIRBORNE) + s_spread_type = M.virus.spread_type + M.virus.spread_type = CONTACT_GENERAL + src.contract_disease(M.virus) + M.virus.spread_type = s_spread_type + return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index c1754a8ad1..090b4a201e 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -56,6 +56,9 @@ usr << "\red [src.name] has a[src.belt.blood_DNA ? " bloody " : " "] \icon[src.belt] [src.belt.name] on [t_his] belt!" else usr << "\blue [src.name] has a \icon[src.belt] [src.belt.name] on [t_his] belt." + if (src.shoes) + usr << "[src.shoes.blood_DNA ? "\red" : "\blue"] [src.name] has a[src.shoes.blood_DNA ? " bloody " : " "] \icon[src.shoes] [src.shoes.name] on [t_his] feet." + if (src.gloves) if (src.gloves.blood_DNA) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 164dcf4dd2..b91ab49506 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1248,6 +1248,7 @@ return /mob/living/carbon/human/attack_paw(mob/M as mob) + ..() if (M.a_intent == "help") src.sleeping = 0 src.resting = 0 @@ -1438,6 +1439,8 @@ M << "No attacking people at spawn, you jackass." return + ..() + if ((M.gloves && M.gloves.elecgen == 1 && M.a_intent == "hurt") /*&& (!istype(src:wear_suit, /obj/item/clothing/suit/judgerobe))*/) if(M.gloves.uses > 0) M.gloves.uses-- diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 840353fb30..c0e3f96477 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -150,6 +150,7 @@ return /mob/living/carbon/monkey/attack_paw(mob/M as mob) + ..() if (M.a_intent == "help") src.sleeping = 0 @@ -173,6 +174,7 @@ return /mob/living/carbon/monkey/attack_hand(mob/M as mob) + ..() if (M.a_intent == "help") src.sleeping = 0 diff --git a/goonstation.dme b/goonstation.dme index f0ff0f0b0b..96e6205137 100644 --- a/goonstation.dme +++ b/goonstation.dme @@ -27,6 +27,7 @@ #define FILE_DIR "code/FEA" #define FILE_DIR "code/game" #define FILE_DIR "code/game/area" +#define FILE_DIR "code/game/asteroid" #define FILE_DIR "code/game/gamemodes" #define FILE_DIR "code/game/gamemodes/blob" #define FILE_DIR "code/game/gamemodes/changeling" @@ -54,6 +55,8 @@ #define FILE_DIR "code/game/machinery/pipe" #define FILE_DIR "code/game/magic" #define FILE_DIR "code/game/magic/cultist" +#define FILE_DIR "code/game/mecha" +#define FILE_DIR "code/game/mecha/combat" #define FILE_DIR "code/game/objects" #define FILE_DIR "code/game/objects/alien" #define FILE_DIR "code/game/objects/closets" @@ -260,6 +263,9 @@ #include "code\game\vote.dm" #include "code\game\area\ai_monitored.dm" #include "code\game\area\areas.dm" +#include "code\game\asteroid\asteroid.dm" +#include "code\game\asteroid\device.dm" +#include "code\game\asteroid\turf.dm" #include "code\game\gamemodes\events.dm" #include "code\game\gamemodes\game_mode.dm" #include "code\game\gamemodes\gameticker.dm" @@ -395,6 +401,9 @@ #include "code\game\magic\cultist\rune8.dm" #include "code\game\magic\cultist\rune9.dm" #include "code\game\magic\cultist\specialtalisman.dm" +#include "code\game\mecha\mecha.dm" +#include "code\game\mecha\combat\combat.dm" +#include "code\game\mecha\combat\gygax.dm" #include "code\game\objects\assemblies.dm" #include "code\game\objects\blood.dm" #include "code\game\objects\bomb.dm" diff --git a/icons/mob/mecha.dmi b/icons/mob/mecha.dmi new file mode 100644 index 0000000000..9fcc6e8de9 Binary files /dev/null and b/icons/mob/mecha.dmi differ diff --git a/icons/turf/walls.dmi b/icons/turf/walls.dmi index d2401cdcd7..18ec15976d 100644 Binary files a/icons/turf/walls.dmi and b/icons/turf/walls.dmi differ diff --git a/maps/trunkmap.dmm b/maps/trunkmap.dmm index 533d78a5ee..2583323830 100644 --- a/maps/trunkmap.dmm +++ b/maps/trunkmap.dmm @@ -743,9 +743,9 @@ "aoo" = (/obj/table{dir = 5; icon_state = "tabledir"},/obj/item/weapon/storage/toolbox/electrical,/obj/machinery/light{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/obj/item/weapon/screwdriver,/obj/item/weapon/hand_labeler,/turf/simulated/floor,/area/ai_monitored/storage/eva) "aop" = (/obj/cable{icon_state = "0-4"; d2 = 4},/obj/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{name = "EVA APC"; pixel_y = -24},/turf/simulated/floor,/area/ai_monitored/storage/eva) "aoq" = (/obj/cable{icon_state = "1-2"; d1 = 1; d2 = 2},/obj/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/ai_monitored/storage/eva) -"aor" = (/obj/rack{dir = 4},/obj/machinery/light,/turf/simulated/floor,/area/ai_monitored/storage/eva) +"aor" = (/obj/rack{dir = 4},/obj/machinery/light,/obj/landmark{name = "ExplorationPack"},/turf/simulated/floor,/area/ai_monitored/storage/eva) "aos" = (/obj/rack{dir = 4},/obj/item/clothing/suit/space,/obj/item/clothing/head/helmet/space,/obj/item/clothing/mask/medical,/obj/item/device/radio/intercom{pixel_y = -24},/turf/simulated/floor,/area/ai_monitored/storage/eva) -"aot" = (/obj/rack{dir = 8},/obj/machinery/light,/turf/simulated/floor,/area/ai_monitored/storage/eva) +"aot" = (/obj/rack{dir = 8},/obj/machinery/light,/obj/landmark{name = "ExplorationPack"},/turf/simulated/floor,/area/ai_monitored/storage/eva) "aou" = (/obj/cable{icon_state = "1-2"; d1 = 1; d2 = 2},/obj/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/ai_monitored/storage/eva) "aov" = (/obj/table{icon_state = "tabledir"; dir = 8},/obj/item/weapon/sheet/glass{amount = 50},/obj/machinery/light{tag = "icon-tube1 (EAST)"; icon_state = "tube1"; dir = 4},/turf/simulated/floor,/area/ai_monitored/storage/eva) "aow" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/simple,/turf/simulated/floor/plating,/area/maintenance/fsmaint)