diff --git a/game/external/discord.cpp b/game/external/discord.cpp index 38cd3e504b..c662b24a0f 100644 --- a/game/external/discord.cpp +++ b/game/external/discord.cpp @@ -60,13 +60,20 @@ void set_discord_rpc(int state) { gDiscordRpcEnabled = state; } +// get base level name from sublevel ("wascitya" -> "wascity") +const char* get_base_level_name(const std::map& level_name_remap, + const char* level_name) { + // ignore sublevels + auto it = level_name_remap.find(level_name); + return (it == level_name_remap.end() ? level_name : it->second).c_str(); +} + // get full level name from symbol name ("village1" -> "Sandover Village") const char* get_full_level_name(const std::map& level_names, const std::map& level_name_remap, const char* level_name) { // ignore sublevels - auto it = level_name_remap.find(level_name); - auto actual_level_name = it == level_name_remap.end() ? level_name : it->second; + auto actual_level_name = get_base_level_name(level_name_remap, level_name); const auto& nice_name = level_names.find(actual_level_name); if (nice_name != level_names.end()) { diff --git a/game/external/discord.h b/game/external/discord.h index d7db4080a6..8d48a9c488 100644 --- a/game/external/discord.h +++ b/game/external/discord.h @@ -18,6 +18,8 @@ std::string get_time_of_day(float time); const char* get_full_level_name(const std::map& level_names, const std::map& level_name_remap, const char* level_name); +const char* get_base_level_name(const std::map& level_name_remap, + const char* level_name); bool indoors(std::vector indoor_levels, const char* level_name); void handleDiscordReady(const DiscordUser* user); diff --git a/game/external/discord_jak3.cpp b/game/external/discord_jak3.cpp index 4d14fc0b8d..f1e193650e 100644 --- a/game/external/discord_jak3.cpp +++ b/game/external/discord_jak3.cpp @@ -35,8 +35,9 @@ const std::map level_names = { // for remapping sub-level names to the matching one in level_names std::map level_name_remap = { - {"introcst", "intro"}, {"templex", "temple"}, {"combx", "comb"}, {"volcanox", "volcano"}, - {"railx", "rail"}, {"railb2", "rail"}, {"rubblea2", "rubble"}, {"wasstada", "wasstad"}, + {"introcst", "intro"}, {"templex", "temple"}, {"combx", "comb"}, {"volcanox", "volcano"}, + {"volcanoa", "volcano"}, {"railx", "rail"}, {"railb2", "rail"}, {"rubblea2", "rubble"}, + {"wasstada", "wasstad"}, {"lfacrm2", "factory"}, }; const std::map> level_remap_hack = { diff --git a/game/kernel/jak3/kmachine_extras.cpp b/game/kernel/jak3/kmachine_extras.cpp index 1ac38b1e43..956d35f733 100644 --- a/game/kernel/jak3/kmachine_extras.cpp +++ b/game/kernel/jak3/kmachine_extras.cpp @@ -21,11 +21,11 @@ AutoSplitterBlock g_auto_splitter_block_jak3; void update_discord_rpc(u32 discord_info) { if (gDiscordRpcEnabled) { DiscordRichPresence rpc; - char state[128]; - char large_image_key[128]; - char large_image_text[128]; - char small_image_key[128]; - char small_image_text[128]; + char state[128] = {}; + char large_image_key[128] = {}; + char large_image_text[128] = {}; + char small_image_key[128] = {}; + char small_image_text[128] = {}; auto info = discord_info ? Ptr(discord_info).c() : NULL; if (info) { // Get the data from GOAL @@ -47,6 +47,7 @@ void update_discord_rpc(u32 discord_info) { float percent_completed = info->percent_completed; std::bitset<64> focus_status = info->focus_status; auto vehicle = static_cast(info->current_vehicle); + auto gun = static_cast(info->active_gun); char* task = Ptr(info->task).c()->data(); // Construct the DiscordRPC Object @@ -59,8 +60,8 @@ void update_discord_rpc(u32 discord_info) { } else { // if we are in an outdoors level, use the picture for the corresponding time of day if (!indoors(indoor_levels, level)) { - char level_with_tod[128]; - strcpy(level_with_tod, level); + char level_with_tod[128] = {}; + strcpy(level_with_tod, get_base_level_name(level_name_remap, level)); strcat(level_with_tod, "-"); strcat(level_with_tod, time_of_day_str(time)); strcpy(large_image_key, level_with_tod); @@ -96,21 +97,23 @@ void update_discord_rpc(u32 discord_info) { strcpy(small_image_key, "focus-status-mech"); strcpy(small_image_text, "Controlling a Dark Maker bot"); } else if (FOCUS_TEST(focus_status, FocusStatus::Pilot)) { - // TODO vehicle images strcpy(small_image_key, "focus-status-pilot"); auto vehicle_name = VehicleTypeToString(vehicle); if (!strcmp(task, "comb-travel") || !strcmp(task, "comb-wild-ride")) { + strcpy(small_image_key, vehicle_type_to_string.at(VehicleType::h_sled).c_str()); strcpy(small_image_text, "Driving the Catacombs Rail Rider"); } else if (!strcmp(task, "desert-glide")) { - strcpy(small_image_text, "Flying the Glider"); + strcpy(small_image_key, vehicle_type_to_string.at(VehicleType::h_glider).c_str()); + strcpy(small_image_text, "Flying the Monk Glider"); } else if (!strcmp(task, "factory-sky-battle")) { + strcpy(small_image_key, vehicle_type_to_string.at(VehicleType::h_hellcat).c_str()); strcpy(small_image_text, "Flying the Hellcat"); } else { if (vehicle_name != "Unknown") { + strcpy(small_image_key, vehicle_type_to_string.at(vehicle).c_str()); strcpy(small_image_text, fmt::format("Driving the {}", vehicle_name).c_str()); } else { - strcpy(small_image_key, ""); - strcpy(small_image_text, ""); + strcpy(small_image_text, "Driving a Zoomer"); } } } else if (FOCUS_TEST(focus_status, FocusStatus::Indax)) { @@ -124,10 +127,16 @@ void update_discord_rpc(u32 discord_info) { strcpy(small_image_text, "Light Jak"); } else if (FOCUS_TEST(focus_status, FocusStatus::Turret)) { strcpy(small_image_key, "focus-status-turret"); - strcpy(small_image_text, "In a Gunpod"); + strcpy(small_image_text, "In a Turret"); } else if (FOCUS_TEST(focus_status, FocusStatus::Gun)) { - strcpy(small_image_key, "focus-status-gun"); - strcpy(small_image_text, "Using a Gun"); + auto gun_name = PickupTypeToString(gun); + if (gun_name != "Unknown") { + strcpy(small_image_key, pickup_type_to_string.at(gun).c_str()); + strcpy(small_image_text, fmt::format("Using the {}", gun_name).c_str()); + } else { + strcpy(small_image_key, "gun-none"); + strcpy(small_image_text, "Using a Gun"); + } } else { strcpy(small_image_key, ""); strcpy(small_image_text, ""); diff --git a/game/kernel/jak3/kmachine_extras.h b/game/kernel/jak3/kmachine_extras.h index ebbbc9ce36..112a1ac801 100644 --- a/game/kernel/jak3/kmachine_extras.h +++ b/game/kernel/jak3/kmachine_extras.h @@ -66,6 +66,7 @@ struct DiscordInfo { u64 focus_status; // uint64 s32 current_vehicle; // int32 u32 task; // string + s32 active_gun; // pickup-type }; enum class VehicleType : s32 { @@ -100,17 +101,118 @@ enum class VehicleType : s32 { Max = 30 }; +enum class PickupType : s32 { + none = 0, + eco_yellow = 1, + eco_red = 2, + eco_blue = 3, + eco_dark = 4, + eco_green = 5, + eco_pill_green = 6, + eco_pill_dark = 7, + eco_pill_light = 8, + eco_pill_random = 9, + money = 10, + fuel_cell = 11, + buzzer = 12, + darkjak = 13, + lightjak = 14, + ammo_yellow = 15, + ammo_red = 16, + ammo_blue = 17, + ammo_dark = 18, + shield = 19, + health = 20, + trick_point = 21, + trick_judge = 22, + gem = 23, + skill = 24, + karma = 25, + gun_red_1 = 26, + gun_red_2 = 27, + gun_red_3 = 28, + gun_yellow_1 = 29, + gun_yellow_2 = 30, + gun_yellow_3 = 31, + gun_blue_1 = 32, + gun_blue_2 = 33, + gun_blue_3 = 34, + gun_dark_1 = 35, + gun_dark_2 = 36, + gun_dark_3 = 37, + board = 38, + pass_red = 39, + pass_green = 40, + pass_yellow = 41, + pass_blue = 42, + ammo_random = 43, + health_max = 44, + light_eco_crystal = 45, + dark_eco_crystal = 46, + pass_slumb_genb = 47, + ammo_light_random = 48, + ammo_dark_light_random = 49, + light_random = 50, + Max = 51, +}; + +const std::map vehicle_type_to_string = { + {VehicleType::v_turtle, "v-turtle"}, + {VehicleType::v_snake, "v-snake"}, + {VehicleType::v_toad, "v-toad"}, + {VehicleType::v_scorpion, "v-scorpion"}, + {VehicleType::v_fox, "v-fox"}, + {VehicleType::v_rhino, "v-rhino"}, + {VehicleType::v_mirage, "v-mirage"}, + {VehicleType::v_x_ride, "v-x-ride"}, + {VehicleType::v_faccar, "v-faccar"}, + {VehicleType::v_marauder, "v-marauder"}, + {VehicleType::v_marauder_b, "v-marauder-b"}, + {VehicleType::h_hellcat, "h-hellcat"}, + {VehicleType::h_sled, "h-sled"}, + {VehicleType::h_glider, "h-glider"}, +}; + const std::map vehicle_remap = { - {VehicleType::v_turtle, "Tough Puppy"}, {VehicleType::v_snake, "Sand Shark"}, - {VehicleType::v_toad, "Dune Hopper"}, {VehicleType::v_scorpion, "Gila Stomper"}, - {VehicleType::v_fox, "Heat Seeker"}, {VehicleType::v_rhino, "Slam Dozer"}, - {VehicleType::v_mirage, "Dust Demon"}, {VehicleType::v_x_ride, "Desert Screamer"}, + {VehicleType::v_turtle, "Tough Puppy"}, + {VehicleType::v_snake, "Sand Shark"}, + {VehicleType::v_toad, "Dune Hopper"}, + {VehicleType::v_scorpion, "Gila Stomper"}, + {VehicleType::v_fox, "Heat Seeker"}, + {VehicleType::v_rhino, "Slam Dozer"}, + {VehicleType::v_mirage, "Dust Demon"}, + {VehicleType::v_x_ride, "Desert Screamer"}, + {VehicleType::v_faccar, "Factory Car"}, + {VehicleType::v_marauder, "Marauder Buggy"}, + {VehicleType::v_marauder_b, "Marauder Leader Buggy"}, +}; + +const std::map pickup_type_to_string = { + {PickupType::gun_red_1, "gun-red-1"}, {PickupType::gun_red_2, "gun-red-2"}, + {PickupType::gun_red_3, "gun-red-3"}, {PickupType::gun_yellow_1, "gun-yellow-1"}, + {PickupType::gun_yellow_2, "gun-yellow-2"}, {PickupType::gun_yellow_3, "gun-yellow-3"}, + {PickupType::gun_blue_1, "gun-blue-1"}, {PickupType::gun_blue_2, "gun-blue-2"}, + {PickupType::gun_blue_3, "gun-blue-3"}, {PickupType::gun_dark_1, "gun-dark-1"}, + {PickupType::gun_dark_2, "gun-dark-2"}, {PickupType::gun_dark_3, "gun-dark-3"}, +}; + +const std::map pickup_remap = { + {PickupType::gun_red_1, "Scatter Gun"}, {PickupType::gun_red_2, "Wave Concussor"}, + {PickupType::gun_red_3, "Plasmite RPG"}, {PickupType::gun_yellow_1, "Blaster Mod"}, + {PickupType::gun_yellow_2, "Beam Reflexor"}, {PickupType::gun_yellow_3, "Gyro Burster"}, + {PickupType::gun_blue_1, "Vulcan Fury"}, {PickupType::gun_blue_2, "Arc Wielder"}, + {PickupType::gun_blue_3, "Needle Lazer"}, {PickupType::gun_dark_1, "Peace Maker"}, + {PickupType::gun_dark_2, "Mass Inverter"}, {PickupType::gun_dark_3, "Super Nova"}, }; inline std::string VehicleTypeToString(VehicleType v) { return vehicle_remap.find(v) != vehicle_remap.end() ? vehicle_remap.at(v) : "Unknown"; } +inline std::string PickupTypeToString(PickupType p) { + return pickup_remap.find(p) != pickup_remap.end() ? pickup_remap.at(p) : "Unknown"; +} + enum class FocusStatus : u64 { Disable = 0, Dead = 1, diff --git a/goal_src/jak3/engine/game/task/task-control.gc b/goal_src/jak3/engine/game/task/task-control.gc index 64a6352719..b82b3efb8e 100644 --- a/goal_src/jak3/engine/game/task/task-control.gc +++ b/goal_src/jak3/engine/game/task/task-control.gc @@ -3412,7 +3412,11 @@ (when (and ; (not (gg-node? node)) (task-node-open? (the game-task-node i)) (!= (-> node description) (the text-id 0)) - (= (-> *task-level* task-level-idx) (-> node level))) + ;; small hack for desert-glide: hanga has task-level volcano, but the task node has task-level desert... + (or (and (= (-> level name) 'hanga) + (or (= (the game-task-node i) (game-task-node desert-glide-templetop)) + (= (the game-task-node i) (game-task-node desert-glide-resolution)))) + (= (-> *task-level* task-level-idx) (-> node level)))) (set! (-> info task) (game-task->string (-> node task))) (return (lookup-text! *common-text* (-> node description) #f)) ) diff --git a/goal_src/jak3/pc/pckernel-impl.gc b/goal_src/jak3/pc/pckernel-impl.gc index f105e9fa70..1fbe8c1361 100644 --- a/goal_src/jak3/pc/pckernel-impl.gc +++ b/goal_src/jak3/pc/pckernel-impl.gc @@ -142,6 +142,7 @@ (focus-status uint64) (current-vehicle int32) (task string) ;; currenly active game-task used for mission specific images + (active-gun int32) ) ) diff --git a/goal_src/jak3/pc/pckernel.gc b/goal_src/jak3/pc/pckernel.gc index 80960cb518..f613958874 100644 --- a/goal_src/jak3/pc/pckernel.gc +++ b/goal_src/jak3/pc/pckernel.gc @@ -302,6 +302,20 @@ "are we in an actual cutscene and should letterbox the view?" (and (!= #f *scene-player*) (nonzero? movie?) (movie?))) +(defun print-rpc-info ((this discord-info) (buf object)) + (format buf "[~8x] discord-info~%" this) + (format buf "~Torb-count: ~f~%" (-> this orb-count)) + (format buf "~Tgem-count: ~f~%" (-> this gem-count)) + (format buf "~Tdeath-count: ~f~%" (-> this death-count)) + (format buf "~Tlevel: ~A~%" (-> this level)) + (format buf "~Tstatus: ~S~%" (-> this status)) + (format buf "~Ttask: ~S~%" (-> this task)) + (format buf "~Tfocus: (~S)~%" (begin (clear *temp-string*) (bit-enum->string focus-status (-> this focus-status) *temp-string*) *temp-string*)) + (format buf "~Tgun: (~S)~%" (begin (clear *temp-string*) (string-format (pickup-type->string (the pickup-type (-> this active-gun)))) *temp-string*)) + (format buf "~Tvehicle: ~S~%" (enum->string vehicle-type (-> this current-vehicle))) + this + ) + (defmethod update-discord-rpc ((obj pc-settings-jak3)) "update discord rpc module" (let ((info (new 'stack 'discord-info))) @@ -326,6 +340,8 @@ (set! (-> info percent-complete) (calculate-percentage *game-info*)) (set! (-> info focus-status) (if *target* (-> *target* focus-status) 0)) (set! (-> info current-vehicle) (the int (-> *game-info* current-vehicle))) + (set! (-> info active-gun) (if *target* (the int (-> *target* gun using-gun-type)) 0)) + ; (when *debug-segment* (print-rpc-info info *stdcon*)) ;; TODO - update to new with-profiler syntax (pc-discord-rpc-update info) ) diff --git a/goal_src/jak3/pc/progress/progress-draw-pc.gc b/goal_src/jak3/pc/progress/progress-draw-pc.gc index eabd560085..a95347e7e5 100644 --- a/goal_src/jak3/pc/progress/progress-draw-pc.gc +++ b/goal_src/jak3/pc/progress/progress-draw-pc.gc @@ -1514,6 +1514,96 @@ (none) ) +(defmethod draw-option ((this menu-icon-info-option) (arg0 progress) (fnt font-context) (arg2 int) (arg3 symbol)) + (set-alpha! fnt (- 1.0 (-> arg0 menu-transition))) + (set-color! fnt (font-color font-color-32)) + (set-scale! fnt 0.5) + (true! (-> *bigmap* auto-save-icon-flag)) + (set! (-> this sprites 0 tid) (the-as texture-id (get-texture checkpoint level-default-minimap))) + (set! (-> this sprites 0 scale-x) 1.0) + (set! (-> this sprites 0 scale-y) 1.0) + (let ((icon-clr (-> this sprites 0 color-ptr))) + (set! (-> icon-clr 0) 128) + (set! (-> icon-clr 1) 128) + (set! (-> icon-clr 2) 128) + (set! (-> icon-clr 3) (the int (* 128.0 (- 1.0 (-> arg0 menu-transition))))) + ) + (set! (-> this sprites 0 pos z) #xffffff) + (set! (-> this sprites 0 pos w) 0) + (set-hud-piece-position! (-> this sprites 0) 240 160) + (with-dma-buffer-add-bucket ((buf (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id hud-draw-hud-alpha) + ) + (draw (-> this sprites 0) buf (-> *level* level-default) #t) + ) + (set-flags! fnt (font-flags kerning middle middle-vert large)) + (set! (-> fnt origin x) 90.0) + (set! (-> fnt origin y) 80.0) + (set-width! fnt 330) + (set-height! fnt 85) + (when (not (-> *pc-settings* use-vis?)) + (set! (-> fnt origin x) (the float (adjust-game-x (-> fnt origin x)))) + (*! (-> fnt width) (-> *pc-settings* aspect-ratio-reciprocal))) + (print-game-text + (lookup-text! *common-text* (text-id progress-autosave-notice) #f) + fnt + #f + 44 + (bucket-id hud-draw-hud-alpha) + ) + (+! (-> fnt origin y) 115.0) + (set-height! fnt 95) + (print-game-text + (string-format (lookup-text! *common-text* (text-id progress-autosave-remove-warn) #f) 1) + fnt + #f + 44 + (bucket-id hud-draw-hud-alpha) + ) + (+! (-> fnt origin y) 90.0) + (set-height! fnt 50) + (set-color! fnt (font-color font-color-33)) + (draw-highlight-bar arg0 fnt (the int (+ 12.0 (-> fnt origin y))) 24 (-> fnt alpha)) + (print-game-text + (lookup-text! *common-text* (text-id progress-continue) #f) + fnt + #f + 44 + (bucket-id hud-draw-hud-alpha) + ) + (none) + ) + +(defmethod draw-option ((this menu-main-menu-option) (arg0 progress) (fnt font-context) (arg2 int) (arg3 symbol)) + (when (and (nonzero? (-> this name)) (= arg2 (-> arg0 option-index))) + (set-scale! fnt 0.75) + (set-color! fnt (font-color font-color-32)) + (set-alpha! fnt (- 1.0 (-> arg0 menu-transition))) + (set-flags! fnt (font-flags shadow kerning middle large)) + (set-width! fnt (if (= (get-aspect-ratio) 'aspect4x3) 235 175)) + (set-height! fnt 80) + (set! (-> fnt origin x) (the float (if (= (get-aspect-ratio) 'aspect4x3) 140 170))) + (set! (-> fnt origin y) (the float (if (= (get-aspect-ratio) 'aspect4x3) 180 175))) + (when (not (-> *pc-settings* use-vis?)) + (set! (-> fnt origin x) (the float (adjust-game-x (-> fnt origin x)))) + (*! (-> fnt width) (-> *pc-settings* aspect-ratio-reciprocal))) + (cond + ((= (-> this name) (text-id progress-bigmap)) + (if (language? french) + (set-scale! fnt 0.7) + ) + (print-game-text (lookup-text! *common-text* (-> this name) #f) fnt #f 44 (bucket-id hud-draw-hud-alpha)) + (set! (-> fnt origin y) (the float (if (= (get-aspect-ratio) 'aspect4x3) 210 200))) + (set-scale! fnt 0.6) + ) + (else + (print-game-text (lookup-text! *common-text* (-> this name) #f) fnt #f 44 (bucket-id hud-draw-hud-alpha)) + ) + ) + ) + (none) + ) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; CUSTOM MENU OPTIONS diff --git a/goal_src/jak3/pc/progress/progress-static-pc.gc b/goal_src/jak3/pc/progress/progress-static-pc.gc index 655b6ffa3d..77981a172c 100644 --- a/goal_src/jak3/pc/progress/progress-static-pc.gc +++ b/goal_src/jak3/pc/progress/progress-static-pc.gc @@ -62,12 +62,13 @@ This gives us more freedom to write code how we want. (set! (-> *setting-control* user-default dialog-volume) val))) (new 'static 'menu-generic-carousel-option :name (text-id progress-sound-format) - :get-max-size-fn (lambda () 3) + :get-max-size-fn (lambda () 2) ; 3 :get-item-label-fn (lambda ((index int)) (case index ((0) (lookup-text! *common-text* (text-id progress-sound-mono) #f)) ((1) (lookup-text! *common-text* (text-id progress-sound-stereo) #f)) - ((2) (lookup-text! *common-text* (text-id progress-sound-surround) #f)))) + ; ((2) (lookup-text! *common-text* (text-id progress-sound-surround) #f)) + )) :get-item-index-fn (lambda () (-> *setting-control* user-default stereo-mode)) :on-confirm (lambda ((index int) (the-progress progress)) (set! (-> *setting-control* user-default stereo-mode) index)))))