Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactors monkecoin rewards + challenges to use /datum/player_details #4536

Merged
merged 4 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 29 additions & 22 deletions code/__HELPERS/~monkestation-helpers/roundend.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,35 @@
/datum/controller/subsystem/ticker/proc/distribute_rewards()
var/hour = round((world.time - SSticker.round_start_time) / 36000)
var/minute = round(((world.time - SSticker.round_start_time) - (hour * 36000)) / 600)
var/added_xp = round(25 + (minute**0.85))
var/added_xp = round(25 + (minute ** 0.85))
for(var/client/client as anything in GLOB.clients)
if(!istype(client) || QDELING(client))
continue
if(!QDELETED(client?.prefs))
client?.prefs?.adjust_metacoins(client?.ckey, 75, "Played a Round")
client?.prefs?.adjust_metacoins(client?.ckey, client?.reward_this_person, "Special Bonus")
// WHYYYYYY
if(QDELETED(client))
continue
if(client?.mob?.mind?.assigned_role)
add_jobxp(client, added_xp, client?.mob?.mind?.assigned_role?.title)
distribute_rewards_to_client(client, added_xp)

/datum/controller/subsystem/ticker/proc/distribute_rewards_to_client(client/client, added_xp)
if(!istype(client) || QDELING(client))
return
var/datum/player_details/details = get_player_details(client)
if(!QDELETED(client?.prefs))
client?.prefs?.adjust_metacoins(client?.ckey, 75, "Played a Round")
var/bonus = details?.roundend_monkecoin_bonus
if(bonus)
client?.prefs?.adjust_metacoins(client?.ckey, bonus, "Special Bonus")
// WHYYYYYY
if(QDELETED(client))
continue
if(length(client?.applied_challenges))
var/mob/living/client_mob = client?.mob
if(!istype(client_mob) || QDELING(client_mob) || client_mob?.stat == DEAD)
return
if(client?.mob?.mind?.assigned_role)
add_jobxp(client, added_xp, client?.mob?.mind?.assigned_role?.title)
if(QDELETED(client))
return
var/list/applied_challenges = details?.applied_challenges
if(LAZYLEN(applied_challenges))
var/mob/living/client_mob = client?.mob
if(!istype(client_mob) || QDELING(client_mob) || client_mob?.stat == DEAD)
return
var/total_payout = 0
for(var/datum/challenge/listed_challenge as anything in applied_challenges)
if(listed_challenge.failed)
continue
var/total_payout = 0
for(var/datum/challenge/listed_challenge as anything in client?.applied_challenges)
if(listed_challenge.failed)
continue
total_payout += listed_challenge.challenge_payout
if(total_payout)
client?.prefs?.adjust_metacoins(client?.ckey, total_payout, "Challenge rewards.")
total_payout += listed_challenge.challenge_payout
if(total_payout)
client?.prefs?.adjust_metacoins(client?.ckey, total_payout, "Challenge rewards.")
9 changes: 4 additions & 5 deletions code/_onclick/hud/new_player.dm
Original file line number Diff line number Diff line change
Expand Up @@ -300,11 +300,10 @@

/atom/movable/screen/lobby/button/intents/Click(location, control, params)
. = ..()
if(!hud.mymob.client.challenge_menu)
var/datum/challenge_selector/new_tgui = new(hud.mymob)
new_tgui.ui_interact(hud.mymob)
else
hud.mymob.client.challenge_menu.ui_interact(hud.mymob)
var/datum/player_details/details = get_player_details(hud.mymob)
details.challenge_menu ||= new(details)
details.challenge_menu.ui_interact(hud.mymob)

/atom/movable/screen/lobby/button/discord
icon = 'icons/hud/lobby/bottom_buttons.dmi'
icon_state = "discord"
Expand Down
42 changes: 24 additions & 18 deletions code/controllers/subsystem/ticker.dm
Original file line number Diff line number Diff line change
Expand Up @@ -523,27 +523,33 @@ SUBSYSTEM_DEF(ticker)

return output

/datum/controller/subsystem/ticker/proc/transfer_single_character(mob/dead/new_player/player)
var/mob/living = player.transfer_character()
if(!living)
return
qdel(player)
ADD_TRAIT(living, TRAIT_NO_TRANSFORM, SS_TICKER_TRAIT)
if(living.client)
var/atom/movable/screen/splash/splash = new(null, living.client, TRUE)
splash.Fade(TRUE)
living.client?.init_verbs()
. = living
var/datum/player_details/details = get_player_details(living)
if(details)
SSchallenges.apply_challenges(details)
for(var/processing_reward_bitflags in bitflags_to_reward)//you really should use department bitflags if possible
if(living.mind.assigned_role.departments_bitflags & processing_reward_bitflags)
details.roundend_monkecoin_bonus += 150
for(var/processing_reward_jobs in jobs_to_reward)//just in case you really only want to reward a specific job
if(living.job == processing_reward_jobs)
details.roundend_monkecoin_bonus += 150

/datum/controller/subsystem/ticker/proc/transfer_characters()
var/list/livings = list()
for(var/mob/dead/new_player/player as anything in GLOB.new_player_list)
var/mob/living = player.transfer_character()
if(living)
qdel(player)
ADD_TRAIT(living, TRAIT_NO_TRANSFORM, SS_TICKER_TRAIT)
if(living.client)
var/atom/movable/screen/splash/S = new(null, living.client, TRUE)
S.Fade(TRUE)
living.client.init_verbs()
livings += living
if(living.client && length(living.client?.active_challenges))
SSchallenges.apply_challenges(living.client)
for(var/processing_reward_bitflags in bitflags_to_reward)//you really should use department bitflags if possible
if(living.mind.assigned_role.departments_bitflags & processing_reward_bitflags)
living.client.reward_this_person += 150
for(var/processing_reward_jobs in jobs_to_reward)//just in case you really only want to reward a specific job
if(living.job == processing_reward_jobs)
living.client.reward_this_person += 150
if(livings.len)
livings += transfer_single_character(player)
list_clear_nulls(livings)
if(length(livings))
addtimer(CALLBACK(src, PROC_REF(release_characters), livings), 3 SECONDS, TIMER_CLIENT_TIME)

/datum/controller/subsystem/ticker/proc/release_characters(list/livings)
Expand Down
3 changes: 0 additions & 3 deletions code/modules/client/client_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,6 @@
/// Does this client have typing indicators enabled?
var/typing_indicators = FALSE

/// used for rewarding players monkecoins at round end
var/reward_this_person = 0

/// Does this client's mob need to rebuild its plane masters after login?
/// This is currently only used so a client can switch between 515 and 516 without breaking their rendering.
var/rebuild_plane_masters = FALSE
6 changes: 6 additions & 0 deletions code/modules/client/player_details.dm
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ GLOBAL_LIST_EMPTY_TYPED(player_details, /datum/player_details)
src.ckey = ckey(player_key)
achievements = new(src.ckey)

/datum/player_details/Destroy(force)
if(!force)
stack_trace("Something is trying to delete player details for [ckey]")
return QDEL_HINT_LETMELIVE
return ..()

/// Returns the full version string (i.e 515.1642) of the BYOND version and build.
/datum/player_details/proc/full_byond_version()
if(!byond_version)
Expand Down
17 changes: 9 additions & 8 deletions code/modules/mob/dead/new_player/new_player.dm
Original file line number Diff line number Diff line change
Expand Up @@ -197,14 +197,15 @@
SSjob.EquipRank(character, job, character.client)
job.after_latejoin_spawn(character)

if(character.client && length(character.client?.active_challenges))
SSchallenges.apply_challenges(character.client)
for(var/processing_reward_bitflags in SSticker.bitflags_to_reward)//you really should use department bitflags if possible
if(character.mind.assigned_role.departments_bitflags & processing_reward_bitflags)
character.client.reward_this_person += 425
for(var/processing_reward_jobs in SSticker.jobs_to_reward)//just in case you really only want to reward a specific job
if(character.job == processing_reward_jobs)
character.client.reward_this_person += 425
var/datum/player_details/details = get_player_details(character)
if(details)
SSchallenges.apply_challenges(details)
for(var/processing_reward_bitflags in SSticker.bitflags_to_reward)//you really should use department bitflags if possible
if(character.mind.assigned_role.departments_bitflags & processing_reward_bitflags)
details.roundend_monkecoin_bonus += 425
for(var/processing_reward_jobs in SSticker.jobs_to_reward)//just in case you really only want to reward a specific job
if(character.job == processing_reward_jobs)
details.roundend_monkecoin_bonus += 425
#define IS_NOT_CAPTAIN 0
#define IS_ACTING_CAPTAIN 1
#define IS_FULL_CAPTAIN 2
Expand Down
25 changes: 22 additions & 3 deletions monkestation/code/modules/client/player_details.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,39 @@
var/datum/patreon_data/patreon
/// Twitch subscription data for this player.
var/datum/twitch_data/twitch
/// Currently active challenges.
var/list/datum/challenge/active_challenges
/// Currently applied challenges.
var/list/datum/challenge/applied_challenges
/// The challenge menu for this mob.
var/datum/challenge_selector/challenge_menu
/// Bonus monkecoins to reward this player at roundend.
var/roundend_monkecoin_bonus = 0

/datum/player_details/New(player_key)
. = ..()
patreon = new(src)
twitch = new(src)

/// Finds the current mob this player is in control of.
/datum/player_details/proc/find_current_mob() as /mob
RETURN_TYPE(/mob)
var/client/client = GLOB.directory[ckey]
. = client?.mob
if(.)
return
for(var/mob/mob as anything in GLOB.mob_list)
if(!QDELETED(mob) && mob.ckey == ckey)
return mob

/**
* Gets a player details instance from a variable, whether it be a mob, a client, or a ckey.
*/
/proc/get_player_details(target) as /datum/player_details
RETURN_TYPE(/datum/player_details)
if(istext(target))
if(istype(target, /datum/player_details))
return target // well, that was easy
else if(istext(target))
return GLOB.player_details[ckey(target)]
else if(ismob(target))
var/mob/mob_target = target
Expand All @@ -27,6 +48,4 @@
else if(IS_CLIENT_OR_MOCK(target))
var/datum/client_interface/client_target = target
return client_target.player_details
else if(istype(target, /datum/player_details))
return target // well, that was easy

Original file line number Diff line number Diff line change
@@ -1,39 +1,43 @@
/client
var/list/active_challenges = list()
var/list/applied_challenges = list()

/datum/challenge
///the challenge name
var/challenge_name = "God's Weakest Challenge"
///the challenge payout
var/challenge_payout = 100
///our host
var/client/host
var/datum/player_details/host
///have we failed if we are a fail action
var/failed = FALSE
///the difficulty of the channgle
var/difficulty = "Easy"
///do we need to process?
var/processes = FALSE
///the current mob we are in
var/mob/current_mob
///the trait we apply if any
var/applied_trait

/datum/challenge/New(client/creator)
/datum/challenge/New(datum/player_details/host)
. = ..()
if(!creator)
return
host = creator
current_mob = host.mob
if(!host)
return
RegisterSignal(host.mob, COMSIG_MIND_TRANSFERRED, PROC_REF(on_transfer))
src.host = host
var/mob/current_mob = host.find_current_mob()
if(!current_mob)
CRASH("Couldn't find mob for [host]")
RegisterSignal(current_mob, COMSIG_MIND_TRANSFERRED, PROC_REF(on_transfer))

/datum/challenge/Destroy(force)
host = null
return ..()

///we just use the client to try and apply this as its easier to track mobs
/datum/challenge/proc/on_apply(client/owner)
if(applied_trait)
ADD_TRAIT(host.mob, applied_trait, CHALLENGE_TRAIT)
/datum/challenge/proc/on_apply()
SHOULD_CALL_PARENT(TRUE)
LAZYADD(host.applied_challenges, src)
if(!applied_trait)
return
var/mob/current_mob = host.find_current_mob()
if(!current_mob)
CRASH("Couldn't find mob for [host]")
ADD_TRAIT(current_mob, applied_trait, CHALLENGE_TRAIT)

///this fires every 10 seconds
/datum/challenge/proc/on_process()
Expand All @@ -47,9 +51,8 @@
/datum/challenge/proc/on_revive()
return

/datum/challenge/proc/on_transfer(datum/source, mob/previous_body)
/datum/challenge/proc/on_transfer(datum/mind/source, mob/previous_body)
SIGNAL_HANDLER
if(applied_trait)
REMOVE_TRAIT(previous_body, applied_trait, CHALLENGE_TRAIT)
var/datum/mind/mind = source
ADD_TRAIT(mind.current, applied_trait, CHALLENGE_TRAIT)
ADD_TRAIT(source.current, applied_trait, CHALLENGE_TRAIT)
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
icon = FA_ICON_OPTIN_MONSTER

/datum/quirk/extra_sensory_paranoia/add()
var/datum/brain_trauma/magic/stalker/T = new()
var/mob/living/carbon/human/H = quirk_holder
H.gain_trauma(T, TRAUMA_RESILIENCE_ABSOLUTE)
var/mob/living/carbon/human/human_holder = quirk_holder
if(ishuman(human_holder))
human_holder.gain_trauma(/datum/brain_trauma/magic/stalker, TRAUMA_RESILIENCE_ABSOLUTE)

/datum/quirk/extra_sensory_paranoia/remove()
var/mob/living/carbon/human/H = quirk_holder
H.cure_trauma_type(/datum/brain_trauma/magic/stalker, TRAUMA_RESILIENCE_ABSOLUTE)
var/mob/living/carbon/human/human_holder = quirk_holder
if(ishuman(human_holder))
human_holder.cure_trauma_type(/datum/brain_trauma/magic/stalker, TRAUMA_RESILIENCE_ABSOLUTE)

/datum/challenge/paranoia
challenge_name = "Paranoia"
Expand All @@ -21,36 +22,29 @@
applied_trait = TRAIT_PARANOIA
var/added = FALSE


/datum/challenge/paranoia/on_apply(client/owner)
/datum/challenge/paranoia/on_apply()
. = ..()
var/mob/living/carbon/human/H = host.mob
if(!ishuman(H))
var/mob/living/carbon/human/current_human = host.find_current_mob()
if(!ishuman(current_human))
return
var/datum/brain_trauma/magic/stalker/T = new()
H.gain_trauma(T, TRAUMA_RESILIENCE_ABSOLUTE)
current_human.gain_trauma(/datum/brain_trauma/magic/stalker, TRAUMA_RESILIENCE_ABSOLUTE)
added = TRUE

/datum/challenge/paranoia/on_process()
if(added)
return

var/mob/living/carbon/human/H = host.mob
if(!ishuman(H))
var/mob/living/carbon/human/current_human = host.find_current_mob()
if(!ishuman(current_human))
return
var/datum/brain_trauma/magic/stalker/T = new()
H.gain_trauma(T, TRAUMA_RESILIENCE_ABSOLUTE)
current_human.gain_trauma(/datum/brain_trauma/magic/stalker, TRAUMA_RESILIENCE_ABSOLUTE)
added = TRUE

/datum/challenge/paranoia/on_transfer(datum/source, mob/previous_body)
/datum/challenge/paranoia/on_transfer(datum/mind/source, mob/previous_body)
. = ..()
var/mob/living/carbon/human/H = previous_body
H.cure_trauma_type(/datum/brain_trauma/magic/stalker, TRAUMA_RESILIENCE_ABSOLUTE)
var/mob/living/carbon/human/previous_human = previous_body
if(ishuman(previous_human))
previous_human.cure_trauma_type(/datum/brain_trauma/magic/stalker, TRAUMA_RESILIENCE_ABSOLUTE)

var/datum/mind/mind = source
var/datum/brain_trauma/magic/stalker/T = new()
if(isliving(mind.current))
var/mob/living/carbon/human/current_human = mind.current
if(!ishuman(current_human))
return
current_human.gain_trauma(T, TRAUMA_RESILIENCE_ABSOLUTE)
var/mob/living/carbon/human/current_human = source.current
if(ishuman(current_human))
current_human.gain_trauma(/datum/brain_trauma/magic/stalker, TRAUMA_RESILIENCE_ABSOLUTE)
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ SUBSYSTEM_DEF(challenges)
for(var/datum/challenge/listed as anything in processing_challenges)
listed.on_process()

/datum/controller/subsystem/challenges/proc/apply_challenges(client/owner)
/datum/controller/subsystem/challenges/proc/apply_challenges(datum/player_details/owner)
owner = get_player_details(owner)
if(!owner)
CRASH("Attempted to apply challenges to invalid owner")
for(var/datum/challenge/listed as anything in owner.active_challenges)
var/datum/challenge/new_challenge = new listed(owner)
if(new_challenge.processes)
processing_challenges += processing_challenges
new_challenge.on_apply(owner)
owner.applied_challenges += new_challenge
LAZYADD(owner.applied_challenges, new_challenge)


Loading
Loading