diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index ec34b6632f3..1f5f4c87421 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -250,6 +250,10 @@ CREATE TABLE `player` ( `nanoui_fancy` smallint(4) DEFAULT '1', `show_ghostitem_attack` smallint(4) DEFAULT '1', `lastchangelog` varchar(32) NOT NULL DEFAULT '0', + `lastchangelog` varchar(32) NOT NULL, + `space_parallax` smallint(4) DEFAULT '1', + `space_dust` smallint(4) DEFAULT '1', + `parallax_speed` float(24) DEFAULT '2', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) ) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=latin1; diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql index b5115a93caf..1349ca6f349 100644 --- a/SQL/paradise_schema_prefixed.sql +++ b/SQL/paradise_schema_prefixed.sql @@ -250,6 +250,10 @@ CREATE TABLE `SS13_player` ( `nanoui_fancy` smallint(4) DEFAULT '1', `show_ghostitem_attack` smallint(4) DEFAULT '1', `lastchangelog` varchar(32) NOT NULL DEFAULT '0', + `lastchangelog` varchar(32) NOT NULL, + `space_parallax` smallint(4) DEFAULT '1', + `space_dust` smallint(4) DEFAULT '1', + `parallax_speed` float(24) DEFAULT '2', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) ) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=latin1; diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 0852622f2c6..530f322c847 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -80,6 +80,14 @@ //turfs += centerturf return atoms +/proc/trange(rad = 0, turf/centre = null) //alternative to range (ONLY processes turfs and thus less intensive) + if(!centre) + return + + var/turf/x1y1 = locate(((centre.x-rad)<1 ? 1 : centre.x-rad),((centre.y-rad)<1 ? 1 : centre.y-rad),centre.z) + var/turf/x2y2 = locate(((centre.x+rad)>world.maxx ? world.maxx : centre.x+rad),((centre.y+rad)>world.maxy ? world.maxy : centre.y+rad),centre.z) + return block(x1y1,x2y2) + /proc/get_dist_euclidian(atom/Loc1 as turf|mob|obj,atom/Loc2 as turf|mob|obj) var/dx = Loc1.x - Loc2.x var/dy = Loc1.y - Loc2.y diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index 51e0dfa8ab2..a531f22ce86 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -72,4 +72,9 @@ var/timezoneOffset = 0 // The difference betwen midnight (of the host computer) // For FTP requests. (i.e. downloading runtime logs.) // However it'd be ok to use for accessing attack logs and such too, which are even laggier. -var/fileaccess_timer = 0 \ No newline at end of file +var/fileaccess_timer = 0 + +//SPACE PARALLAX +var/parallax_initialized = 0 +var/space_color = "#050505" +var/list/parallax_icon[27] \ No newline at end of file diff --git a/code/_onclick/_defines.dm b/code/_onclick/_defines.dm index a02a1f43590..84ef776b41b 100644 --- a/code/_onclick/_defines.dm +++ b/code/_onclick/_defines.dm @@ -1,3 +1,8 @@ #define CLICKCATCHER_PLANE -99 +#define PLANE_SPACE_BACKGROUND -10 +#define PLANE_SPACE_PARALLAX (PLANE_SPACE_BACKGROUND + 1) +#define PLANE_SPACE_DUST (PLANE_SPACE_PARALLAX + 1) +#define PLANE_BASE 0 + #define HUD_PLANE 90 \ No newline at end of file diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 29e7c676ac4..cce5cdb37fa 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -167,6 +167,7 @@ mymob.update_action_buttons(1) reorganize_alerts() reload_fullscreen() + update_parallax_and_dust() /datum/hud/human/show_hud(version = 0) ..() diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm new file mode 100644 index 00000000000..e5018468aad --- /dev/null +++ b/code/_onclick/hud/parallax.dm @@ -0,0 +1,281 @@ +/* + * This file handles all parallax-related business once the parallax itself is initialized with the rest of the HUD + */ + +var/list/parallax_on_clients = list() + +/obj/screen/parallax + var/base_offset_x = 0 + var/base_offset_y = 0 + mouse_opacity = 0 + icon = 'icons/turf/space.dmi' + icon_state = "blank" + name = "space parallax" + blend_mode = BLEND_ADD + layer = AREA_LAYER + plane = PLANE_SPACE_PARALLAX + var/parallax_speed = 0 + var/last_accumulated_offset_x = 0 + var/last_accumulated_offset_y = 0 + +/obj/screen/plane_master + appearance_flags = PLANE_MASTER + screen_loc = "1,1" + +/obj/screen/plane_master/parallax_master + plane = PLANE_SPACE_PARALLAX + blend_mode = BLEND_MULTIPLY + color = list( + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 0, + 0, 0, 0, 1) + +/obj/screen/plane_master/parallax_spacemaster // Turns space-turfs into white. The parallax plane multiplies itself by the white, causing the parallax to only show in areas with opacity. + plane = PLANE_SPACE_BACKGROUND + color = list( + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0) + +/obj/screen/plane_master/parallax_dustmaster + plane = PLANE_SPACE_DUST + +/datum/hud/proc/update_parallax() + var/client/C = mymob.client + if(!parallax_initialized || C.updating_parallax) return + + for(var/turf/space/T in trange(C.view,get_turf(C.eye))) + C.updating_parallax = 1 + break + + if(!C.updating_parallax) + return + + //multiple sub-procs for profiling purposes + if(update_parallax1()) + update_parallax2(0) + update_parallax3() + C.updating_parallax = 0 + else + C.updating_parallax = 0 + +/datum/hud/proc/update_parallax_and_dust() + var/client/C = mymob.client + if(!parallax_initialized || C.updating_parallax) return + C.updating_parallax = 1 + if(update_parallax1()) + update_parallax2(1) + update_parallax3() + C.updating_parallax = 0 + else + C.updating_parallax = 0 + +/datum/hud/proc/update_parallax1() + var/client/C = mymob.client + //DO WE UPDATE PARALLAX + if(C.prefs.space_parallax)//have to exclude Centcom so parallax doens't appear during hyperspace + parallax_on_clients |= C + else + for(var/obj/screen/parallax/bgobj in C.parallax) + C.screen -= bgobj + parallax_on_clients -= C + C.screen -= C.parallax_master + C.screen -= C.parallax_spacemaster + C.screen -= C.parallax_dustmaster + return 0 + + if(!C.parallax_master) + C.parallax_master = new /obj/screen/plane_master/parallax_master + if(!C.parallax_spacemaster) + C.parallax_spacemaster = new /obj/screen/plane_master/parallax_spacemaster + if(!C.parallax_dustmaster) + C.parallax_dustmaster = new /obj/screen/plane_master/parallax_dustmaster + return 1 + +/datum/hud/proc/update_parallax2(forcerecalibrate = 0) + var/client/C = mymob.client + //DO WE HAVE TO REPLACE ALL THE LAYERS + + if(!C.parallax.len) + for(var/obj/screen/parallax/bgobj in parallax_icon) + var/obj/screen/parallax/parallax_layer = new /obj/screen/parallax + parallax_layer.appearance = bgobj.appearance + parallax_layer.base_offset_x = bgobj.base_offset_x + parallax_layer.base_offset_y = bgobj.base_offset_y + parallax_layer.parallax_speed = bgobj.parallax_speed + C.parallax += parallax_layer + + var/parallax_loaded = 0 + for(var/obj/screen/parallax/S in C.screen) + parallax_loaded = 1 + break + + if(forcerecalibrate || !parallax_loaded) + for(var/obj/screen/parallax/bgobj in C.parallax) + C.screen |= bgobj + + C.screen |= C.parallax_master + C.screen |= C.parallax_spacemaster + C.screen |= C.parallax_dustmaster + C.parallax_dustmaster.color = list(0,0,0,0) + if(C.prefs.space_dust) + C.parallax_dustmaster.color = list( + 1,0,0,0, + 0,1,0,0, + 0,0,1,0, + 0,0,0,1) + + if(!C.parallax_offset.len) + C.parallax_offset["horizontal"] = 0 + C.parallax_offset["vertical"] = 0 + +/datum/hud/proc/update_parallax3() + var/client/C = mymob.client + //ACTUALLY MOVING THE PARALLAX + var/turf/posobj = get_turf(C.eye) + + if(!C.previous_turf || (C.previous_turf.z != posobj.z)) + C.previous_turf = posobj + + var/x_diff = posobj.x - C.previous_turf.x + var/y_diff = posobj.y - C.previous_turf.y + if(x_diff == 0 && y_diff == 0) + return // Nothing to do here. + var/world_time = world.time + var/last_delay = world_time - C.last_parallax_shift + last_delay = min(last_delay, 4) + + //Doing it this way prevents parallax layers from "jumping" when you change Z-Levels. + C.parallax_offset["horizontal"] += x_diff + C.parallax_offset["vertical"] += y_diff + + C.previous_turf = posobj + C.last_parallax_shift = world_time + + for(var/obj/screen/parallax/bgobj in C.parallax) + if(bgobj.parallax_speed)//only the middle and front layers actually move + var/accumulated_offset_x = bgobj.base_offset_x - round(C.parallax_offset["horizontal"] * bgobj.parallax_speed * (C.prefs.parallax_speed/2)) + var/accumulated_offset_y = bgobj.base_offset_y - round(C.parallax_offset["vertical"] * bgobj.parallax_speed * (C.prefs.parallax_speed/2)) + + bgobj.last_accumulated_offset_x = accumulated_offset_x + bgobj.last_accumulated_offset_y = accumulated_offset_y + + while(accumulated_offset_x > 720) + accumulated_offset_x -= 1440 + while(accumulated_offset_x < -720) + accumulated_offset_x += 1440 + + while(accumulated_offset_y > 720) + accumulated_offset_y -= 1440 + while(accumulated_offset_y < -720) + accumulated_offset_y += 1440 + + bgobj.screen_loc = "CENTER-7:[accumulated_offset_x],CENTER-7:[accumulated_offset_y]" + else + bgobj.screen_loc = "CENTER-7:[bgobj.base_offset_x],CENTER-7:[bgobj.base_offset_y]" + +//Parallax generation code below + +#define PARALLAX4_ICON_NUMBER 20 +#define PARALLAX3_ICON_NUMBER 14 +#define PARALLAX2_ICON_NUMBER 10 + +/datum/controller/game_controller/proc/cachespaceparallax() + var/list/plane1 = list() + var/list/plane2 = list() + var/list/plane3 = list() + var/list/pixel_x = list() + var/list/pixel_y = list() + var/index = 1 + for(var/i = 0 to 224) + for(var/j = 1 to 9) + plane1 += rand(1,26) + plane2 += rand(1,26) + plane3 += rand(1,26) + pixel_x += 32 * (i%15) + pixel_y += 32 * round(i/15) + + for(var/i in 0 to 8) + var/obj/screen/parallax/parallax_layer = new /obj/screen/parallax() + + var/list/L = list() + for(var/j in 1 to 225) + if(plane1[j+i*225] <= PARALLAX4_ICON_NUMBER) + var/image/I = image('icons/turf/space_parallax4.dmi',"[plane1[j+i*225]]") + I.pixel_x = pixel_x[j] + I.pixel_y = pixel_y[j] + I.plane = PLANE_SPACE_PARALLAX + L += I + + parallax_layer.overlays = L + parallax_layer.parallax_speed = 0 + parallax_layer.plane = PLANE_SPACE_PARALLAX + calibrate_parallax(parallax_layer,i+1) + parallax_icon[index] = parallax_layer + index++ + + for(var/i in 0 to 8) + var/obj/screen/parallax/parallax_layer = new /obj/screen/parallax() + + var/list/L = list() + for(var/j in 1 to 225) + if(plane2[j+i*225] <= PARALLAX3_ICON_NUMBER) + var/image/I = image('icons/turf/space_parallax3.dmi',"[plane2[j+i*225]]") + I.pixel_x = pixel_x[j] + I.pixel_y = pixel_y[j] + I.plane = PLANE_SPACE_PARALLAX + L += I + + parallax_layer.overlays = L + parallax_layer.parallax_speed = 1 + parallax_layer.plane = PLANE_SPACE_PARALLAX + calibrate_parallax(parallax_layer,i+1) + parallax_icon[index] = parallax_layer + index++ + + for(var/i in 0 to 8) + var/obj/screen/parallax/parallax_layer = new /obj/screen/parallax() + var/list/L = list() + for(var/j in 1 to 225) + if(plane3[j+i*225] <= PARALLAX2_ICON_NUMBER) + var/image/I = image('icons/turf/space_parallax2.dmi',"[plane3[j+i*225]]") + I.pixel_x = pixel_x[j] + I.pixel_y = pixel_y[j] + I.plane = PLANE_SPACE_PARALLAX + L += I + + parallax_layer.overlays = L + parallax_layer.parallax_speed = 2 + parallax_layer.plane = PLANE_SPACE_PARALLAX + calibrate_parallax(parallax_layer,i+1) + parallax_icon[index] = parallax_layer + index++ + + parallax_initialized = 1 + +/proc/calibrate_parallax(var/obj/screen/parallax/p_layer,var/i) + if(!p_layer || !i) return + + /* Placement of screen objects + 1 2 3 + 4 5 6 + 7 8 9 + */ + switch(i) + if(1,4,7) + p_layer.base_offset_x = -480 + if(3,6,9) + p_layer.base_offset_x = 480 + switch(i) + if(1,2,3) + p_layer.base_offset_y = 480 + if(7,8,9) + p_layer.base_offset_y = -480 + +#undef PARALLAX4_ICON_NUMBER +#undef PARALLAX3_ICON_NUMBER +#undef PARALLAX2_ICON_NUMBER \ No newline at end of file diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index c3c0ea77ddb..7e2308a4026 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -53,6 +53,11 @@ var/global/pipe_processing_killed = 0 setupgenetics() setupfactions() setup_economy() + + var/watch = start_watch() + log_startup_progress("Caching space parallax simulation...") + cachespaceparallax() + log_startup_progress(" Finished caching space parallax simulation in [stop_watch(watch)]s.") for(var/i=0, i
" + dat += "Parallax Speed: [parallax_speed]
" + dat += "Space Dust: [space_dust ? "Yes" : "No"]
" dat += "Fancy NanoUI: [(nanoui_fancy) ? "Yes" : "No"]
" dat += "Ghost-Item Attack Animation: [(show_ghostitem_attack) ? "Yes" : "No"]
" dat += "Custom UI settings:
" @@ -1755,6 +1761,21 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts var/mob/living/carbon/human/H = usr H.remake_hud() + if("parallax") + space_parallax = !space_parallax + + if(usr && usr.hud_used) + usr.hud_used.update_parallax_and_dust() + + if("dust") + space_dust = !space_dust + + if(usr && usr.hud_used) + usr.hud_used.update_parallax_and_dust() + + if("p_speed") + parallax_speed = min(max(input(user, "Enter a number between 0 and 5 included (default=2)","Parallax Speed Preferences",parallax_speed),0),5) + if("be_special") var/r = href_list["role"] if(!(r in special_roles)) @@ -2017,4 +2038,4 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts popup.open(0) /datum/preferences/proc/close_load_dialog(mob/user) - user << browse(null, "window=saves") \ No newline at end of file + user << browse(null, "window=saves") diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index f72ac076dff..be47a7c1183 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -13,7 +13,10 @@ volume, nanoui_fancy, show_ghostitem_attack, - lastchangelog + lastchangelog, + space_parallax, + space_dust, + parallax_speed FROM [format_table_name("player")] WHERE ckey='[C.ckey]'"} ) @@ -40,6 +43,9 @@ nanoui_fancy = text2num(query.item[11]) show_ghostitem_attack = text2num(query.item[12]) lastchangelog = query.item[13] + space_parallax = text2num(query.item[14]) + space_dust = text2num(query.item[15]) + parallax_speed = text2num(query.item[16]) //Sanitize ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor)) @@ -54,6 +60,9 @@ nanoui_fancy = sanitize_integer(nanoui_fancy, 0, 1, initial(nanoui_fancy)) show_ghostitem_attack = sanitize_integer(show_ghostitem_attack, 0, 1, initial(show_ghostitem_attack)) lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog)) + space_parallax = sanitize_integer(space_parallax, 0, 1, initial(space_parallax)) + space_dust = sanitize_integer(space_dust, 0, 1, initial(space_dust)) + parallax_speed = sanitize_integer(parallax_speed, 0, 5, initial(parallax_speed)) return 1 /datum/preferences/proc/save_preferences(client/C) @@ -78,7 +87,10 @@ volume='[volume]', nanoui_fancy='[nanoui_fancy]', show_ghostitem_attack='[show_ghostitem_attack]', - lastchangelog='[lastchangelog]' + lastchangelog='[lastchangelog]', + space_parallax='[space_parallax]', + space_dust='[space_dust]', + parallax_speed='[parallax_speed]' WHERE ckey='[C.ckey]'"} ) diff --git a/code/modules/client/preference/preferences_toggles.dm b/code/modules/client/preference/preferences_toggles.dm index 541dee07242..a1ba6d907d6 100644 --- a/code/modules/client/preference/preferences_toggles.dm +++ b/code/modules/client/preference/preferences_toggles.dm @@ -213,4 +213,45 @@ set category = "Preferences" set desc = "Allows you to access the Setup Character screen. Changes to your character won't take effect until next round, but other changes will." prefs.current_tab = 1 - prefs.ShowChoices(usr) \ No newline at end of file + prefs.ShowChoices(usr) + +/client/verb/toggle_space_parallax() + set name = "Toggle Space Parallax" + set category = "Preferences" + set desc = "Toggle the parallax effect of space turfs." + prefs.space_parallax = !prefs.space_parallax + + prefs.save_preferences(src) + + if(!prefs.space_parallax) + to_chat(usr, "Space parallax is now deactivated.") + else + to_chat(usr, "Space parallax is now activated.") + + if(mob && mob.hud_used) + mob.hud_used.update_parallax_and_dust() + +/client/verb/toggle_space_dust() + set name = "Toggle Space Dust" + set category = "Preferences" + set desc = "Toggle the presence of dust on space turfs." + prefs.space_dust = !prefs.space_dust + + prefs.save_preferences(src) + + if(!prefs.space_dust) + to_chat(usr, "Space dust is now deactivated.") + else + to_chat(usr, "Space dust is now activated.") + + if(mob && mob.hud_used) + mob.hud_used.update_parallax_and_dust() + +/client/verb/toggle_parallax_speed() + set name = "Change Parallax Speed" + set category = "Preferences" + set desc = "Change the speed at which parallax moves." + + prefs.parallax_speed = min(max(input(usr, "Enter a number between 0 and 5 included (default=2)","Parallax Speed Preferences",prefs.parallax_speed),0),5) + + prefs.save_preferences(src) \ No newline at end of file diff --git a/icons/turf/screen1_parallax.dmi b/icons/turf/screen1_parallax.dmi new file mode 100644 index 00000000000..cd0f232bbc4 Binary files /dev/null and b/icons/turf/screen1_parallax.dmi differ diff --git a/icons/turf/space.dmi b/icons/turf/space.dmi index 60fdfce3861..4e27e4086be 100644 Binary files a/icons/turf/space.dmi and b/icons/turf/space.dmi differ diff --git a/icons/turf/space_parallax1.dmi b/icons/turf/space_parallax1.dmi new file mode 100644 index 00000000000..a538bf0f0d1 Binary files /dev/null and b/icons/turf/space_parallax1.dmi differ diff --git a/icons/turf/space_parallax2.dmi b/icons/turf/space_parallax2.dmi new file mode 100644 index 00000000000..e93cc831d49 Binary files /dev/null and b/icons/turf/space_parallax2.dmi differ diff --git a/icons/turf/space_parallax3.dmi b/icons/turf/space_parallax3.dmi new file mode 100644 index 00000000000..2261ab17f71 Binary files /dev/null and b/icons/turf/space_parallax3.dmi differ diff --git a/icons/turf/space_parallax4.dmi b/icons/turf/space_parallax4.dmi new file mode 100644 index 00000000000..560bacd0090 Binary files /dev/null and b/icons/turf/space_parallax4.dmi differ diff --git a/paradise.dme b/paradise.dme index d79069d135d..96f47272de4 100644 --- a/paradise.dme +++ b/paradise.dme @@ -111,6 +111,7 @@ #include "code\_onclick\hud\monkey.dm" #include "code\_onclick\hud\movable_screen_objects.dm" #include "code\_onclick\hud\other_mobs.dm" +#include "code\_onclick\hud\parallax.dm" #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\swarmer.dm"