[Ready] Deadchat control component, also a chance for deadchat controlled birdboat. (#47110)

* Dead chat controlled singularity!
It just can't go wrong.

Signed-off-by: TheChosenEvilOne <tceo-email@protonmail.com>

* Renames the input_cooldown var to make more sense.

Signed-off-by: TheChosenEvilOne <tceo-email@protonmail.com>

* Begone ugly checks.

Signed-off-by: TheChosenEvilOne <tceo-email@protonmail.com>

* oh yeah, I can just do this.

Signed-off-by: TheChosenEvilOne <tceo-email@protonmail.com>

* Replaced the deadchat control with a component.

Signed-off-by: TheChosenEvilOne <tceo-email@protonmail.com>

* Autodoc

Signed-off-by: TheChosenEvilOne <tceo-email@protonmail.com>

* Removed the leftover global list.

Signed-off-by: TheChosenEvilOne <tceo-email@protonmail.com>

* Possessed goose, bye singularity.

Signed-off-by: TheChosenEvilOne <tceo-email@protonmail.com>

* vomit

Signed-off-by: TheChosenEvilOne <tceo-email@protonmail.com>

* Deadchat plays singularity

Signed-off-by: TheChosenEvilOne <tceo-email@protonmail.com>

* Removed global mode completely, also reviews.

Signed-off-by: TheChosenEvilOne <tceo-email@protonmail.com>

* Reviews.

Signed-off-by: TheChosenEvilOne <tceo-email@protonmail.com>

* alrighty then

Signed-off-by: TheChosenEvilOne <tceo-email@protonmail.com>
This commit is contained in:
TheChosenEvilOne
2019-10-23 22:00:22 +02:00
committed by AnturK
parent d594f03d9f
commit e0bcd2538f
7 changed files with 140 additions and 1 deletions
+4 -1
View File
@@ -114,6 +114,8 @@
#define COMPONENT_BLOCK_TOOL_ATTACK 1
#define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" //called when teleporting into a protected turf: (channel, turf/origin)
#define COMPONENT_BLOCK_TELEPORT 1
#define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin" //called when an atom starts orbiting another atom: (atom)
#define COMSIG_ATOM_ORBIT_STOP "atom_orbit_stop" //called when an atom stops orbiting another atom: (atom)
/////////////////
#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" //from base of atom/attack_ghost(): (mob/dead/observer/ghost)
#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" //from base of atom/attack_hand(): (mob/user)
@@ -204,7 +206,8 @@
#define SPEECH_LANGUAGE 5
#define SPEECH_IGNORE_SPAM 6
#define SPEECH_FORCED 7 */
#define COMSIG_MOB_DEADSAY "mob_deadsay" // from /mob/say_dead(): (mob/speaker, message)
#define MOB_DEADSAY_SIGNAL_INTERCEPT 1
// /mob/living signals
#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living)
+106
View File
@@ -0,0 +1,106 @@
#define DEMOCRACY_MODE "democracy"
#define ANARCHY_MODE "anarchy"
/datum/component/deadchat_control
dupe_mode = COMPONENT_DUPE_UNIQUE
var/timerid
var/list/datum/callback/inputs = list()
var/list/ckey_to_cooldown = list()
var/orbiters = list()
var/deadchat_mode
var/input_cooldown
/datum/component/deadchat_control/Initialize(_deadchat_mode, _inputs, _input_cooldown = 12 SECONDS)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, COMSIG_ATOM_ORBIT_BEGIN, .proc/orbit_begin)
RegisterSignal(parent, COMSIG_ATOM_ORBIT_STOP, .proc/orbit_stop)
deadchat_mode = _deadchat_mode
inputs = _inputs
input_cooldown = _input_cooldown
if(deadchat_mode == DEMOCRACY_MODE)
timerid = addtimer(CALLBACK(src, .proc/democracy_loop), input_cooldown, TIMER_STOPPABLE | TIMER_LOOP)
notify_ghosts("[parent] is now deadchat controllable!", source = parent, action = NOTIFY_ORBIT, header="Something Interesting!")
/datum/component/deadchat_control/Destroy(force, silent)
inputs = null
orbiters = null
ckey_to_cooldown = null
return ..()
/datum/component/deadchat_control/proc/deadchat_react(mob/source, message)
message = lowertext(message)
if(!inputs[message])
return
if(deadchat_mode == ANARCHY_MODE)
var/cooldown = ckey_to_cooldown[source.ckey]
if(cooldown)
return MOB_DEADSAY_SIGNAL_INTERCEPT
inputs[message].Invoke()
ckey_to_cooldown[source.ckey] = TRUE
addtimer(CALLBACK(src, .proc/remove_cooldown, source.ckey), input_cooldown)
else if(deadchat_mode == DEMOCRACY_MODE)
ckey_to_cooldown[source.ckey] = message
return MOB_DEADSAY_SIGNAL_INTERCEPT
/datum/component/deadchat_control/proc/remove_cooldown(ckey)
ckey_to_cooldown.Remove(ckey)
/datum/component/deadchat_control/proc/democracy_loop()
if(QDELETED(parent) || deadchat_mode != DEMOCRACY_MODE)
deltimer(timerid)
return
var/result = count_democracy_votes()
if(!isnull(result))
inputs[result].Invoke()
var/message = "<span class='deadsay italics bold'>[parent] has done action [result]!<br>New vote started. It will end in [input_cooldown/10] seconds.</span>"
for(var/M in orbiters)
to_chat(M, message)
else
var/message = "<span class='deadsay italics bold'>No votes were cast this cycle.</span>"
for(var/M in orbiters)
to_chat(M, message)
/datum/component/deadchat_control/proc/count_democracy_votes()
if(!length(ckey_to_cooldown))
return
var/list/votes = list()
for(var/command in inputs)
votes["[command]"] = 0
for(var/vote in ckey_to_cooldown)
votes[ckey_to_cooldown[vote]]++
ckey_to_cooldown.Remove(vote)
// Solve which had most votes.
var/prev_value = 0
var/result
for(var/vote in votes)
if(votes[vote] > prev_value)
prev_value = votes[vote]
result = vote
if(result in inputs)
return result
/datum/component/deadchat_control/vv_edit_var(var_name, var_value)
. = ..()
if(!.)
return
if(var_name != NAMEOF(src, deadchat_mode))
return
ckey_to_cooldown = list()
if(var_value == DEMOCRACY_MODE)
timerid = addtimer(CALLBACK(src, .proc/democracy_loop), input_cooldown, TIMER_STOPPABLE | TIMER_LOOP)
else
deltimer(timerid)
/datum/component/deadchat_control/proc/orbit_begin(atom/source, atom/orbiter)
RegisterSignal(orbiter, COMSIG_MOB_DEADSAY, .proc/deadchat_react)
orbiters |= orbiter
/datum/component/deadchat_control/proc/orbit_stop(atom/source, atom/orbiter)
if(orbiter in orbiters)
UnregisterSignal(orbiter, COMSIG_MOB_DEADSAY)
orbiters -= orbiter
+2
View File
@@ -60,6 +60,7 @@
orbiters[orbiter] = TRUE
orbiter.orbiting = src
RegisterSignal(orbiter, COMSIG_MOVABLE_MOVED, .proc/orbiter_move_react)
SEND_SIGNAL(parent, COMSIG_ATOM_ORBIT_BEGIN, orbiter)
var/matrix/initial_transform = matrix(orbiter.transform)
// Head first!
@@ -86,6 +87,7 @@
if(!orbiters[orbiter])
return
UnregisterSignal(orbiter, COMSIG_MOVABLE_MOVED)
SEND_SIGNAL(parent, COMSIG_ATOM_ORBIT_STOP, orbiter)
orbiter.SpinAnimation(0, 0)
orbiters -= orbiter
orbiter.stop_orbit(src)
@@ -64,6 +64,10 @@
goosevomit = new
goosevomit.Grant(src)
RegisterSignal(src, COMSIG_MOVABLE_MOVED, .proc/goosement)
// 5% chance every round to have anarchy mode deadchat control on birdboat.
if(prob(5))
desc = "[initial(desc)] It's waddling more than usual. It seems to be possessed."
deadchat_plays_goose()
/mob/living/simple_animal/hostile/retaliate/goose/vomit/Destroy()
UnregisterSignal(src, COMSIG_MOVABLE_MOVED)
@@ -155,6 +159,16 @@
vomitCoefficient = 1
vomitTimeBonus = 0
/// A proc to make it easier for admins to make the goose playable by deadchat.
/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/deadchat_plays_goose()
stop_automated_movement = TRUE
AddComponent(/datum/component/deadchat_control, ANARCHY_MODE, list(
"up" = CALLBACK(GLOBAL_PROC, .proc/_step, src, NORTH),
"down" = CALLBACK(GLOBAL_PROC, .proc/_step, src, SOUTH),
"left" = CALLBACK(GLOBAL_PROC, .proc/_step, src, WEST),
"right" = CALLBACK(GLOBAL_PROC, .proc/_step, src, EAST),
"vomit" = CALLBACK(src, .proc/vomit_prestart, 25)), 12 SECONDS, 4 SECONDS)
/datum/action/cooldown/vomit
name = "Vomit"
check_flags = AB_CHECK_CONSCIOUS
+2
View File
@@ -78,6 +78,8 @@
var/source = "<span class='game'><span class='prefix'>DEAD:</span> <span class='name'>[name]</span>[alt_name]"
var/rendered = " <span class='message'>[emoji_parse(spanned)]</span></span>"
log_talk(message, LOG_SAY, tag="DEAD")
if(SEND_SIGNAL(src, COMSIG_MOB_DEADSAY, message) & MOB_DEADSAY_SIGNAL_INTERCEPT)
return
deadchat_broadcast(rendered, source, follow_target = src, speaker_key = key)
///Check if this message is an emote
@@ -446,3 +446,14 @@
explosion(src.loc,(dist),(dist*2),(dist*4))
qdel(src)
return(gain)
/obj/singularity/deadchat_controlled
move_self = FALSE
/obj/singularity/deadchat_controlled/Initialize(mapload, starting_energy)
. = ..()
AddComponent(/datum/component/deadchat_control, DEMOCRACY_MODE, list(
"up" = CALLBACK(GLOBAL_PROC, .proc/_step, src, NORTH),
"down" = CALLBACK(GLOBAL_PROC, .proc/_step, src, SOUTH),
"left" = CALLBACK(GLOBAL_PROC, .proc/_step, src, WEST),
"right" = CALLBACK(GLOBAL_PROC, .proc/_step, src, EAST)))
+1
View File
@@ -363,6 +363,7 @@
#include "code\datums\components\chasm.dm"
#include "code\datums\components\construction.dm"
#include "code\datums\components\creamed.dm"
#include "code\datums\components\deadchat_control.dm"
#include "code\datums\components\decal.dm"
#include "code\datums\components\dejavu.dm"
#include "code\datums\components\earprotection.dm"