Fixes ghost roles trying to spawn people when there /should/ be zero uses left (#73224)

## About The Pull Request

By means of making a particularly popular ghost role (do NOT put
catgirls on icebox bro you don't know the consequences) I have
discovered a strange bug where despite any of the checks that are in
place, it will still attempt to spawn more people than the role should
allow. I've found the likely caused to be that a lot of people are
clicking the role then clicking spawn at once, and the spawner simply
does not have time to tell everyone "wait no you can't do that" before
it deletes itself from running out of uses.

The solution? Even easier than the reservation thing: Subtract uses
**BEFORE** spawning the mob, as spawning the mob can take some time,
then if it fails to spawn somehow we can refund the uses.

## Why It's Good For The Game

Ghost roles spawning in the nullspace spawn room every now and then is a
bad thing I think.

## Changelog
🆑
fix: Ghost role spawners will now no longer try and spawn people when
they /should/ have been out of uses but due to a bug were not
/🆑
This commit is contained in:
Paxilmaniac
2023-02-10 12:54:49 -05:00
committed by GitHub
parent 32cc189886
commit 8a1cc5ccca
+18 -9
View File
@@ -108,8 +108,10 @@
var/prompt_name = ""
///if false, you won't prompt for this role. best used for replacing the prompt system with something else like a radial, or something.
var/prompt_ghost = TRUE
///how many times this spawner can be used (it won't delete unless it's out of uses)
///how many times this spawner can be used (it won't delete unless it's out of uses and the var to delete itself is set)
var/uses = 1
/// Does the spawner delete itself when it runs out of uses?
var/deletes_on_zero_uses_left = TRUE
////descriptions
@@ -146,16 +148,19 @@
/obj/effect/mob_spawn/ghost_role/attack_ghost(mob/user)
if(!SSticker.HasRoundStarted() || !loc)
return
if(prompt_ghost)
var/ghost_role = tgui_alert(usr, "Become [prompt_name]? (Warning, You can no longer be revived!)",, list("Yes", "No"))
var/ghost_role = tgui_alert(usr, "Become [prompt_name]? (Warning, You can no longer be revived!)", buttons = list("Yes", "No"), timeout = 10 SECONDS)
if(ghost_role != "Yes" || !loc || QDELETED(user))
return
if(!(GLOB.ghost_role_flags & GHOSTROLE_SPAWNER) && !(flags_1 & ADMIN_SPAWNED_1))
to_chat(user, span_warning("An admin has temporarily disabled non-admin ghost roles!"))
return
if(!uses) //just in case
to_chat(user, span_warning("This spawner is out of charges!"))
return
if(is_banned_from(user.key, role_ban))
to_chat(user, span_warning("You are banned from this role!"))
return
@@ -163,8 +168,15 @@
return
if(QDELETED(src) || QDELETED(user))
return
user.log_message("became a [prompt_name].", LOG_GAME)
create(user)
uses -= 1 // Remove a use before trying to spawn to prevent strangeness like the spawner trying to spawn more mobs than it should be able to
if(!(create(user)))
message_admins("[src] didn't return anything when creating a mob, this might be broken! The use of the spawner it would have taken has been refunded.")
uses += 1 // Oops! We messed up and somehow the mob didn't spawn, but that's alright we can refund the use.
check_uses() // Now we check if the spawner should delete itself or not
/obj/effect/mob_spawn/ghost_role/special(mob/living/spawned_mob, mob/mob_possessor)
. = ..()
@@ -182,12 +194,9 @@
spawned_mob.mind.set_assigned_role(SSjob.GetJobType(spawner_job_path))
spawned_mind.name = spawned_mob.real_name
//multiple use mob spawner functionality here- doesn't make sense on corpses
/obj/effect/mob_spawn/ghost_role/create(mob/mob_possessor, newname)
. = ..()
if(uses > 0)
uses--
if(!uses)
/// Checks if the spawner has zero uses left, if so, delete yourself... NOW!
/obj/effect/mob_spawn/ghost_role/proc/check_uses()
if(!uses && deletes_on_zero_uses_left)
qdel(src)
///override this to add special spawn conditions to a ghost role