diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 0f63673c085..b70fad502fc 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -280,6 +280,10 @@ C?.give_award(/datum/award/achievement/misc/threekhours, C.mob) if(hours > 4000) C?.give_award(/datum/award/achievement/misc/fourkhours, C.mob) + //NSV13 - emergency repair achievement hook + if(C && GLOB.plating_repairers["[C.ckey]"] && GLOB.plating_repairers["[C.ckey]"] >= 200) + C.give_award(/datum/award/achievement/misc/emergency_repairs, C.mob) + //NSV13 end CHECK_TICK diff --git a/code/datums/achievements/_achievement_data.dm b/code/datums/achievements/_achievement_data.dm index c3b78a89d02..fce8e09d990 100644 --- a/code/datums/achievements/_achievement_data.dm +++ b/code/datums/achievements/_achievement_data.dm @@ -76,7 +76,7 @@ /datum/achievement_data/proc/increase_score(datum/award/score/achievement_type, mob/user, value) var/datum/award/score/A = SSachievements.awards[achievement_type] get_data(achievement_type) //Get the current status first if necessary - if(length(A.high_scores) == 0 || A.high_scores[A.high_scores[1]] < value) + if(A.announce_highscore && (length(A.high_scores) == 0 || A.high_scores[A.high_scores[1]] < value)) //NSV13 - Adds support for non-spamming scores. to_chat(world, "[user.client.key] set a new high score in [A.name]: [value]") if(!data[achievement_type] || value > data[achievement_type]) data[achievement_type] = value diff --git a/code/datums/achievements/_awards.dm b/code/datums/achievements/_awards.dm index 01b52b8dd81..eb2324101e4 100644 --- a/code/datums/achievements/_awards.dm +++ b/code/datums/achievements/_awards.dm @@ -90,6 +90,8 @@ default_value = 0 var/track_high_scores = TRUE var/list/high_scores = list() + ///Determines whether we announce if we achieve a new highscore. + var/announce_highscore = TRUE //NSV13 - no spammies /datum/award/score/New() . = ..() diff --git a/config/starmap/starmap_default.json b/config/starmap/starmap_default.json index e5f9871a8e3..0bf3032dcca 100644 --- a/config/starmap/starmap_default.json +++ b/config/starmap/starmap_default.json @@ -1146,7 +1146,7 @@ "is_hypergate": 0, "preset_trader": null, "audio_cues": "[]", - "startup_proc": null + "startup_proc": "STARTUP_PROC_TYPE_DOLOS" }, { "name": "Abassi", @@ -1169,7 +1169,7 @@ "is_hypergate": 0, "preset_trader": null, "audio_cues": "[]", - "startup_proc": null + "startup_proc": "STARTUP_PROC_TYPE_ABASSI" }, { "name": "Oasis Fidei", diff --git a/nsv13/code/__DEFINES/medal.dm b/nsv13/code/__DEFINES/medal.dm index 5f2fcb4c76c..06107ab7fc3 100644 --- a/nsv13/code/__DEFINES/medal.dm +++ b/nsv13/code/__DEFINES/medal.dm @@ -2,3 +2,12 @@ #define MEDAL_CREW_VERYCOMPETENT "On the frontlines" #define MEDAL_CREW_EXTREMELYCOMPETENT "Pre-emptive strike" #define MEDAL_CREW_HYPERCOMPETENT "Cleared the Abassi Ridge" + +#define MEDAL_PIRATE_EXTERMINATOR "Pirate Exterminator" +#define MEDAL_FIST_BREAKER "Fist Breaker" +#define MEDAL_TORP_DIRECTHIT "OW!!!" +#define MEDAL_EMERGENCY_REPAIRS "Emergency Repairs" +#define MEDAL_BLACKHOLE_INCIDENT "AAAAAAAAAAAAA" +#define MEDAL_ILLEGAL_TECHNOLOGY "Regulation 10124" + +#define TORPCOUNT_SCORE "Torpedo Technician" diff --git a/nsv13/code/__DEFINES/starsystem.dm b/nsv13/code/__DEFINES/starsystem.dm index 47dbd5c63e7..050249ef105 100644 --- a/nsv13/code/__DEFINES/starsystem.dm +++ b/nsv13/code/__DEFINES/starsystem.dm @@ -13,3 +13,5 @@ #define SECTOR_SOL 1 #define SECTOR_NEUTRAL 2 #define SECTOR_SYNDICATE 3 + +#define COMSIG_STAR_SYSTEM_AFTER_ENTER "star_system_after_enter" diff --git a/nsv13/code/controllers/subsystem/overmap_mode.dm b/nsv13/code/controllers/subsystem/overmap_mode.dm index f0e6b0903a5..921a148c8d9 100644 --- a/nsv13/code/controllers/subsystem/overmap_mode.dm +++ b/nsv13/code/controllers/subsystem/overmap_mode.dm @@ -49,6 +49,11 @@ SUBSYSTEM_DEF(overmap_mode) var/list/modes var/list/mode_names + ///Have we already handed people the base achievement this round? + var/patrol_achievement_base_granted = FALSE + ///Have we already handed people the extended patrol achievement this round? + var/patrol_achievement_adv_granted = FALSE + /datum/controller/subsystem/overmap_mode/Initialize(start_timeofday) //Retrieve the list of modes //Check our map for any white/black lists @@ -458,6 +463,27 @@ SUBSYSTEM_DEF(overmap_mode) mode.winner = F //This should allow the mode to finish up by itself mode.check_finished() if((objective_check >= objective_length) && !failed) + var/achievement_type + if(!SSovermap_mode.round_extended) + if(!SSovermap_mode.patrol_achievement_base_granted) + achievement_type = /datum/award/achievement/misc/crew_competent + SSovermap_mode.patrol_achievement_base_granted = TRUE + else + if(!SSovermap_mode.patrol_achievement_adv_granted) + achievement_type = /datum/award/achievement/misc/crew_very_competent + SSovermap_mode.patrol_achievement_adv_granted = TRUE + if(achievement_type) + for(var/mob/living/living_mob in GLOB.mob_living_list) + if(!living_mob.job) + continue + var/datum/job/job_ref = SSjob.GetJob(living_mob.job) + if(!job_ref) + continue + if(job_ref.faction != "Station") + continue + if(!living_mob.client) + continue + living_mob.client.give_award(achievement_type, living_mob) victory() /datum/overmap_gamemode/proc/victory() diff --git a/nsv13/code/controllers/subsystem/starsystem.dm b/nsv13/code/controllers/subsystem/starsystem.dm index a75482a2061..51445fd48e5 100644 --- a/nsv13/code/controllers/subsystem/starsystem.dm +++ b/nsv13/code/controllers/subsystem/starsystem.dm @@ -384,6 +384,24 @@ Returns a faction datum by its name (case insensitive!) return FALSE return (world.time - info["from_time"])/(info["to_time"] - info["from_time"]) +/datum/controller/subsystem/star_system/proc/dolos_visited(datum/star_system/source, obj/structure/overmap/entering) + SIGNAL_HANDLER + if(entering.ai_controlled) + return + for(var/mob/living/visitor in entering.mobs_in_ship) + if(!visitor.client) + continue + INVOKE_ASYNC(visitor.client, TYPE_PROC_REF(/client, give_award), /datum/award/achievement/misc/crew_extremely_competent, visitor) + +/datum/controller/subsystem/star_system/proc/abassi_visited(datum/star_system/source, obj/structure/overmap/entering) + SIGNAL_HANDLER + if(entering.ai_controlled) + return + for(var/mob/living/visitor in entering.mobs_in_ship) + if(!visitor.client) + continue + INVOKE_ASYNC(visitor.client, TYPE_PROC_REF(/client, give_award), /datum/award/achievement/misc/crew_hypercompetent, visitor) + //////star_system DATUM/////// /datum/star_system @@ -447,6 +465,10 @@ Returns a faction datum by its name (case insensitive!) if("STARTUP_PROC_TYPE_BRASIL_LITE") addtimer(CALLBACK(src, PROC_REF(generate_litelands)), 5 SECONDS) return + if("STARTUP_PROC_TYPE_DOLOS") + addtimer(CALLBACK(src, PROC_REF(register_dolos_achievement)), 5 SECONDS) + if("STARTUP_PROC_TYPE_ABASSI") + addtimer(CALLBACK(src, PROC_REF(register_abassi_achievement)), 5 SECONDS) message_admins("WARNING: Invalid startup_proc declared for [name]! Review your defines (~L438, starsystem.dm), please.") return 1 @@ -661,10 +683,10 @@ Returns a faction datum by its name (case insensitive!) OM.disable_dampeners() RegisterSignal(OM, COMSIG_PARENT_QDELETING, PROC_REF(handle_affecting_del)) for(var/obj/structure/overmap/OM as() in affecting) - if(overmap_dist(src, OM) > influence_range || !z || OM.z != z) + var/dist = overmap_dist(src, OM) + if(dist > influence_range || !z || OM.z != z) stop_affecting(OM) continue - var/dist = get_dist(src, OM) var/grav_level = OVERMAP_SINGULARITY_PROX_GRAVITY if(dist <= redshift_range) var/redshift ="#[num2hex(130-dist,2)][num2hex(0,2)][num2hex(0,2)]" @@ -685,6 +707,7 @@ Returns a faction datum by its name (case insensitive!) if(istype(crushed, /area/space)) continue crushed.has_gravity = OVERMAP_SINGULARITY_DEATH_GRAV //You are dead. + grant_death_achievement(OM) qdel(OM) continue if(grav_tracker[OM] != grav_level) @@ -724,6 +747,12 @@ Returns a faction datum by its name (case insensitive!) cached_colours[deleting] = null UnregisterSignal(deleting, COMSIG_PARENT_QDELETING) +/obj/effect/overmap_anomaly/singularity/proc/grant_death_achievement(obj/structure/overmap/congratulations) + for(var/mob/living/nice_job in congratulations.mobs_in_ship) + if(!nice_job.client) + continue + nice_job.client.give_award(/datum/award/achievement/misc/blackhole_incident, nice_job) + #undef OVERMAP_SINGULARITY_PROX_GRAVITY #undef OVERMAP_SINGULARITY_REDSHIFT_GRAV #undef OVERMAP_SINGULARITY_DANGER_GRAV @@ -1567,6 +1596,17 @@ Random starsystem. Excluded from starmap saving, as they're generated at init. #undef RANDOM_CONNECTION_BASE_CHANCE #undef RANDOM_CONNECTION_REPEAT_PENALTY +/* +These are used to check if someone is visiting one of the special systems. +Handled this way and done on the starsystem controller so we do not conflict with other signals that rely on star systems registering a signal onto themselves. +*/ + +/datum/star_system/proc/register_dolos_achievement() + SSstar_system.RegisterSignal(src, COMSIG_STAR_SYSTEM_AFTER_ENTER, TYPE_PROC_REF(/datum/controller/subsystem/star_system, dolos_visited)) + +/datum/star_system/proc/register_abassi_achievement() + SSstar_system.RegisterSignal(src, COMSIG_STAR_SYSTEM_AFTER_ENTER, TYPE_PROC_REF(/datum/controller/subsystem/star_system, abassi_visited)) + /* Welcome to the endgame. This sector is the hardest you'll encounter in game and holds the Syndicate capital. @@ -1629,6 +1669,7 @@ Welcome to the endgame. This sector is the hardest you'll encounter in game and hidden = FALSE desc = "A place where giants fell. You feel nothing save for an odd sense of unease and an eerie silence." system_traits = STARSYSTEM_NO_ANOMALIES | STARSYSTEM_NO_WORMHOLE + startup_proc = "STARTUP_PROC_TYPE_DOLOS" /datum/star_system/sector4/abassi name = "Abassi" @@ -1644,6 +1685,7 @@ Welcome to the endgame. This sector is the hardest you'll encounter in game and threat_level = THREAT_LEVEL_DANGEROUS hidden = TRUE system_traits = STARSYSTEM_NO_ANOMALIES | STARSYSTEM_NO_WORMHOLE + startup_proc = "STARTUP_PROC_TYPE_ABASSI" /datum/star_system/sector4/laststand name = "Oasis Fidei" //oasis of faith diff --git a/nsv13/code/datums/achievements/nsv_achievements.dm b/nsv13/code/datums/achievements/nsv_achievements.dm index dc44bab2310..60d7f356797 100644 --- a/nsv13/code/datums/achievements/nsv_achievements.dm +++ b/nsv13/code/datums/achievements/nsv_achievements.dm @@ -1,23 +1,69 @@ /datum/award/achievement/misc/crew_competent name = "Patrolling the border" - desc = "FIXME" + desc = "Your first successful patrol!" database_id = MEDAL_CREW_COMPETENT - reward = 500 + reward = 400 + achievement_version = 2 /datum/award/achievement/misc/crew_very_competent name = "On the frontlines" - desc = "FIXME" + desc = "Shore leave? What is that?" database_id = MEDAL_CREW_VERYCOMPETENT - reward = 1000 + reward = 800 + achievement_version = 2 /datum/award/achievement/misc/crew_extremely_competent name = "Pre-emptive strike" - desc = "FIXME" + desc = "See a legendary battlefield with your own eyes." database_id = MEDAL_CREW_EXTREMELYCOMPETENT - reward = 2000 + reward = 1500 + achievement_version = 2 /datum/award/achievement/misc/crew_hypercompetent name = "Cleared the Abassi Ridge" - desc = "FIXME" + desc = "Visit a system few have lived to tell the tale of." database_id = MEDAL_CREW_HYPERCOMPETENT - reward = 5000 + reward = 3000 + achievement_version = 2 + +/datum/award/achievement/misc/pirate_exterminator + name = "Pirate Exterminator" + desc = "Emerge victorious against a powerful pirate foe." + database_id = MEDAL_PIRATE_EXTERMINATOR + reward = 1000 + +/datum/award/achievement/misc/fist_breaker + name = "Fist Breaker" + desc = "Syndicate Battleship? More like Syndicate scrap!" + database_id = MEDAL_FIST_BREAKER + reward = 1000 + +/datum/award/achievement/misc/torp_directhit + name = "OW!!!" + desc = "Have a face-to-face encounter with a torpedo." + database_id = MEDAL_TORP_DIRECTHIT + reward = 200 + +/datum/award/achievement/misc/emergency_repairs + name = "Emergency Repairs" + desc = "Repair a lot of armor plates during a single patrol." + database_id = MEDAL_EMERGENCY_REPAIRS + reward = 1000 + +/datum/award/achievement/misc/blackhole_incident + name = "AAAAAAAAAAAAA" + desc = "Get a little bit too close to a black hole." + database_id = MEDAL_BLACKHOLE_INCIDENT + reward = 200 + +/datum/award/achievement/misc/illegal_technology + name = "Regulation 10124" + desc = "Forget something important." + database_id = MEDAL_ILLEGAL_TECHNOLOGY + reward = 200 + +/datum/award/score/torpcount + name = "Torpedo Technician" + desc = "Better get to making those torps!" + database_id = TORPCOUNT_SCORE + announce_highscore = FALSE //Please do not spam the chat if some muni tech is cooking. diff --git a/nsv13/code/modules/munitions/ammunition/torpedos/torpedo_construction.dm b/nsv13/code/modules/munitions/ammunition/torpedos/torpedo_construction.dm index 3a3a2cc6b9d..c97c802e585 100644 --- a/nsv13/code/modules/munitions/ammunition/torpedos/torpedo_construction.dm +++ b/nsv13/code/modules/munitions/ammunition/torpedos/torpedo_construction.dm @@ -214,13 +214,15 @@ if(tool.use_tool(src, user, 40, amount=1, volume=100)) to_chat(user, "") state = 11 - check_completion() + check_completion(user) return TRUE . = ..() -/obj/item/ship_weapon/ammunition/torpedo/torpedo_casing/proc/check_completion() +/obj/item/ship_weapon/ammunition/torpedo/torpedo_casing/proc/check_completion(mob/user) update_icon() if(state >= 11) + if(user && user.client) + INVOKE_ASYNC(user.client, TYPE_PROC_REF(/client, give_award), /datum/award/score/torpcount, user) new_torpedo(wh, gs, ps, iff) return TRUE diff --git a/nsv13/code/modules/overmap/FTL/ftl_jump.dm b/nsv13/code/modules/overmap/FTL/ftl_jump.dm index 08cbd3547fd..bcdfc6b9120 100644 --- a/nsv13/code/modules/overmap/FTL/ftl_jump.dm +++ b/nsv13/code/modules/overmap/FTL/ftl_jump.dm @@ -42,6 +42,7 @@ after_enter(OM) /datum/star_system/proc/after_enter(obj/structure/overmap/OM) + SEND_SIGNAL(src, COMSIG_STAR_SYSTEM_AFTER_ENTER, OM) if(desc) OM.relay(null, "

Now entering [name]...

") OM.relay(null, "[desc]") diff --git a/nsv13/code/modules/overmap/ai-skynet.dm b/nsv13/code/modules/overmap/ai-skynet.dm index 82be49c4fe0..650158d08c2 100644 --- a/nsv13/code/modules/overmap/ai-skynet.dm +++ b/nsv13/code/modules/overmap/ai-skynet.dm @@ -818,6 +818,19 @@ Adding tasks is easy! Just define a datum for it. fleet_trait = FLEET_TRAIT_DEFENSE reward = 100 //Difficult pirate fleet, so default reward. +/datum/fleet/pirate/tortuga/defeat() + if(!current_system) + return ..() + for(var/obj/structure/overmap/survivor in current_system.system_contents) + if(survivor.ai_controlled) + continue + for(var/mob/living/victorious_mob in survivor.mobs_in_ship) + if(!victorious_mob.client) + continue + victorious_mob.client.give_award(/datum/award/achievement/misc/pirate_exterminator, victorious_mob) + return ..() + + //Boss battles. /datum/fleet/rubicon //Crossing the rubicon, are we? @@ -991,6 +1004,13 @@ Adding tasks is easy! Just define a datum for it. shield_scan_target.hail("Scans have detected that you are in posession of prohibited technology. \n Your IFF signature has been marked as 'persona non grata'. \n In accordance with SGC-reg #10124, your ship and lives are now forfeit. Evacuate all civilian personnel immediately and surrender yourselves.", name) shield_scan_target.relay_to_nearby('nsv13/sound/effects/ship/solgov_scan_alert.ogg', ignore_self=FALSE) shield_scan_target.faction = shield_scan_target.name + grant_oopsie_achievement(shield_scan_target) + +/datum/fleet/solgov/proc/grant_oopsie_achievement(obj/structure/overmap/fugitive) + for(var/mob/living/traitor in fugitive.mobs_in_ship) + if(!traitor.client) + continue + traitor.client.give_award(/datum/award/achievement/misc/illegal_technology, traitor) /datum/fleet/solgov/interdiction name = "\improper Solgov hunter fleet" diff --git a/nsv13/code/modules/overmap/hull_plating.dm b/nsv13/code/modules/overmap/hull_plating.dm index 8904276da2f..033c09f8616 100644 --- a/nsv13/code/modules/overmap/hull_plating.dm +++ b/nsv13/code/modules/overmap/hull_plating.dm @@ -1,3 +1,6 @@ +///A list used to see how has repaired how many plates. +GLOBAL_LIST_EMPTY(plating_repairers) //A tiiny bit inefficient but the only alternative I can see would be messing with the achievement subsystem (I am not doing that) + /obj/structure/hull_plate name = "nanolaminate reinforced hull plating" desc = "A heavy piece of hull plating designed to reinforced the ship's superstructure. The Nanotrasen official starship operational manual states that any damage sustained can be patched up temporarily with a welder." @@ -142,6 +145,11 @@ Method to try locate an overmap object that we should attach to. Recursively cal if(armour_broken) parent?.armour_plates ++ armour_broken = FALSE + if(user && user.client) + if(!GLOB.plating_repairers["[user.client.ckey]"]) + GLOB.plating_repairers["[user.client.ckey]"] = 1 + else + GLOB.plating_repairers["[user.client.ckey]"] = GLOB.plating_repairers["[user.client.ckey]"] + 1 return /obj/structure/hull_plate/update_icon() diff --git a/nsv13/code/modules/overmap/types/syndicate.dm b/nsv13/code/modules/overmap/types/syndicate.dm index df542fc4112..29427a2ebf7 100644 --- a/nsv13/code/modules/overmap/types/syndicate.dm +++ b/nsv13/code/modules/overmap/types/syndicate.dm @@ -496,6 +496,18 @@ weapon_types[FIRE_MODE_FLAK] = new /datum/ship_weapon/flak(src) weapon_types[FIRE_MODE_MISSILE] = new /datum/ship_weapon/missile_launcher(src) +/obj/structure/overmap/syndicate/ai/fistofsol/Destroy() + if(!current_system) + return ..() + for(var/obj/structure/overmap/survivor in (current_system.system_contents - src)) //In case for some reason our Fist is piloted + if(survivor.ai_controlled) + continue + for(var/mob/living/victorious_mob in survivor.mobs_in_ship) + if(!victorious_mob.client) + continue + victorious_mob.client.give_award(/datum/award/achievement/misc/fist_breaker, victorious_mob) + return ..() + /obj/structure/overmap/hostile/ai/alicorn name = "SGV Alicorn" desc = "One Billion Lives!" diff --git a/nsv13/code/modules/overmap/weapons/projectiles_fx.dm b/nsv13/code/modules/overmap/weapons/projectiles_fx.dm index 10e23391736..96b18231f3c 100644 --- a/nsv13/code/modules/overmap/weapons/projectiles_fx.dm +++ b/nsv13/code/modules/overmap/weapons/projectiles_fx.dm @@ -212,6 +212,8 @@ Misc projectile types, effects, think of this as the special FX file. if(isliving(target)) //Someone got bonked by an incendiary torpedo, daamn. var/mob/living/L = target + if(L.client) + L.client.give_award(/datum/award/achievement/misc/torp_directhit, L) if(L.mind && L.mind.assigned_role == "Clown") return (prob(50) ? 2 : -2) //We all know clowns are cursed. return 2 @@ -387,6 +389,10 @@ Misc projectile types, effects, think of this as the special FX file. qdel(P) return FALSE //Didn't take the hit if(!isprojectile(target)) //This is lazy as shit but is necessary to prevent explosions triggering on the overmap when two bullets collide. Fix this shit please. + if(isliving(target)) + var/mob/living/living_target = target + if(living_target.client) + living_target.client.give_award(/datum/award/achievement/misc/torp_directhit, living_target) detonate(target) else return FALSE @@ -558,7 +564,7 @@ Misc projectile types, effects, think of this as the special FX file. /obj/item/projectile/beam/laser/heavylaser/phaser/relayed projectile_piercing = PASSGLASS|PASSGRILLE|PASSTABLE flag = "laser" - damage = 80 //let's give them a chance to live, instead of smiting them with the full wraith of the Enterprise + damage = 80 //let's give them a chance to live, instead of smiting them with the full wraith of the Enterprise /obj/item/projectile/beam/laser/heavylaser/phaser/relayed/on_hit(atom/target, blocked) . = ..() @@ -568,7 +574,7 @@ Misc projectile types, effects, think of this as the special FX file. name = "point defense phaser" damage = 60 // Doesn't scale with power input, but fires fairly quickly especially when upgraded icon = 'nsv13/icons/obj/projectiles_nsv.dmi' - icon_state = "pdphaser" + icon_state = "pdphaser" relay_projectile_type = /obj/item/projectile/beam/laser/phaser/pd/relayed /obj/item/projectile/beam/laser/phaser/pd/relayed