Merge pull request #13909 from silicons/twitch_plays

Twitch Plays: Clown Car
This commit is contained in:
DeltaFire
2021-01-01 04:14:26 +01:00
committed by Archie
parent 8c60d61428
commit 2b79e974eb
9 changed files with 3448 additions and 3303 deletions

View File

@@ -152,18 +152,15 @@
#define COMPONENT_BLOCK_TELEPORT (1<<0)
///called when an atom is added to the hearers on get_hearers_in_view(): (list/processing_list, list/hearers)
#define COMSIG_ATOM_HEARER_IN_VIEW "atom_hearer_in_view"
///called when an atom starts orbiting another atom: (atom)
#define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin"
///called when an atom stops orbiting another atom: (atom)
#define COMSIG_ATOM_ORBIT_STOP "atom_orbit_stop"
/////////////////
///from base of atom/attack_ghost(): (mob/dead/observer/ghost)
#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost"
///from base of atom/attack_hand(): (mob/user)
#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand"
///from base of atom/attack_paw(): (mob/user)
#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw"
#define COMPONENT_NO_ATTACK_HAND (1<<0) //works on all 3.
#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)
#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw" //from base of atom/attack_paw(): (mob/user)
#define COMPONENT_NO_ATTACK_HAND 1 //works on all 3.
/////////////////
//This signal return value bitflags can be found in __DEFINES/misc.dm
///called for each movable in a turf contents on /turf/zImpact(): (atom/movable/A, levels)
@@ -174,6 +171,10 @@
#define COMSIG_LIVING_START_PULL "living_start_pull"
/////////////////
/// Called from orbit component: (atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
#define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin"
/// Called from orbit component: (atom/movable/orbiter, refreshing)
#define COMSIG_ATOM_ORBIT_END "atom_orbit_end"
///from base of area/Entered(): (/area)
#define COMSIG_ENTER_AREA "enter_area"
@@ -708,16 +709,13 @@
#define COMPONENT_ACTION_BLOCK_TRIGGER (1<<0)
//Xenobio hotkeys
#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl" //from slime CtrlClickOn(): (/mob)
#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt" //from slime AltClickOn(): (/mob)
#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift" //from slime ShiftClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob)
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob)
///from slime CtrlClickOn(): (/mob)
#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl"
///from slime AltClickOn(): (/mob)
#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt"
///from slime ShiftClickOn(): (/mob)
#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift"
///from turf ShiftClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift"
///from turf AltClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt"
///from monkey CtrlClickOn(): (/mob)
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl"
// twitch plays
/// Returns direction: (wipe_votes)
#define COMSIG_TWITCH_PLAYS_MOVEMENT_DATA "twitch_plays_movement_data"

View File

@@ -60,6 +60,7 @@
move_react()
/datum/component/orbiter/proc/begin_orbit(atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
SEND_SIGNAL(parent, COMSIG_ATOM_ORBIT_BEGIN, orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
if(orbiter.orbiting)
if(orbiter.orbiting == src)
orbiter.orbiting.end_orbit(orbiter, TRUE)
@@ -99,6 +100,7 @@
/datum/component/orbiter/proc/end_orbit(atom/movable/orbiter, refreshing=FALSE)
if(!orbiters[orbiter])
return
SEND_SIGNAL(parent, COMSIG_ATOM_ORBIT_END, orbiter, refreshing)
UnregisterSignal(orbiter, COMSIG_MOVABLE_MOVED)
orbiter.SpinAnimation(0, 0)
orbiters -= orbiter

View File

@@ -130,7 +130,7 @@
//KEYS
/datum/component/riding/proc/keycheck(mob/user)
return !keytype || user.is_holding_item_of_type(keytype)
return !keytype || user?.is_holding_item_of_type(keytype)
//BUCKLE HOOKS
/datum/component/riding/proc/restore_position(mob/living/buckled_mob)
@@ -150,7 +150,7 @@
/datum/component/riding/proc/handle_ride(mob/user, direction)
var/atom/movable/AM = parent
if(user.incapacitated())
if(user && user.incapacitated())
Unbuckle(user)
return

View File

@@ -0,0 +1,104 @@
/**
* Observers voting on things through orbiting
*/
/datum/component/twitch_plays
/// Observers
var/list/mob/players = list()
/datum/component/twitch_plays/Initialize(...)
. = ..()
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, COMSIG_ATOM_ORBIT_BEGIN, .proc/on_start_orbit)
RegisterSignal(parent, COMSIG_ATOM_ORBIT_END, .proc/on_end_orbit)
/datum/component/twitch_plays/Destroy(force, silent)
for(var/i in players)
DetachPlayer(i)
return ..()
/datum/component/twitch_plays/proc/on_start_orbit(datum/source, atom/movable/orbiter)
if(!isobserver(orbiter))
return
AttachPlayer(orbiter)
/datum/component/twitch_plays/proc/on_end_orbit(datum/source, atom/movable/orbiter)
if(!(orbiter in players))
return
DetachPlayer(orbiter)
/datum/component/twitch_plays/proc/AttachPlayer(mob/dead/observer)
players |= observer
RegisterSignal(observer, COMSIG_PARENT_QDELETING, .proc/on_end_orbit)
/datum/component/twitch_plays/proc/DetachPlayer(mob/dead/observer)
players -= observer
UnregisterSignal(observer, COMSIG_PARENT_QDELETING)
/// Simple movement one
/datum/component/twitch_plays/simple_movement
/// Movement votes by observer
var/list/votes = list()
/// Allow diagonals
var/allow_diagonal = FALSE
/datum/component/twitch_plays/simple_movement/Initialize(...)
. = ..()
if(. & COMPONENT_INCOMPATIBLE)
return
RegisterSignal(parent, COMSIG_TWITCH_PLAYS_MOVEMENT_DATA, .proc/fetch_data)
/datum/component/twitch_plays/simple_movement/AttachPlayer(mob/dead/observer)
. = ..()
RegisterSignal(observer, COMSIG_MOVABLE_PRE_MOVE, .proc/pre_move)
/datum/component/twitch_plays/simple_movement/DetachPlayer(mob/dead/observer)
. = ..()
UnregisterSignal(observer, COMSIG_MOVABLE_PRE_MOVE)
/datum/component/twitch_plays/simple_movement/proc/pre_move(datum/source, turf/newLoc)
if(get_dist(newLoc, parent) > 1) // they're trying to escape orbit
return
. = COMPONENT_MOVABLE_BLOCK_PRE_MOVE
var/dir = get_dir(parent, newLoc)
if(!dir)
return
if(allow_diagonal || !((dir - 1) & dir))
votes[source] = dir
else // pick one or the other
votes[source] = prob(50)? (dir & ~(dir - 1)) : (dir & (dir - 1))
/datum/component/twitch_plays/simple_movement/proc/fetch_data(datum/source, wipe_votes)
if(!votes.len)
return
var/list/total = list(TEXT_NORTH, TEXT_SOUTH, TEXT_EAST, TEXT_WEST)
for(var/i in votes)
total[num2text(votes[i])] += 1
. = text2num(pickweight(total, 0))
if(wipe_votes)
votes.len = 0
/datum/component/twitch_plays/simple_movement/auto
var/move_delay = 2
var/last_move = 0
/datum/component/twitch_plays/simple_movement/auto/Initialize(...)
if(!ismovable(parent))
return COMPONENT_INCOMPATIBLE
. = ..()
if(. & COMPONENT_INCOMPATIBLE)
return
START_PROCESSING(SSfastprocess, src)
/datum/component/twitch_plays/simple_movement/auto/Destroy(force, silent)
STOP_PROCESSING(SSfastprocess, src)
return ..()
/datum/component/twitch_plays/simple_movement/auto/process()
var/dir = fetch_data(null, TRUE)
if(!dir)
return
if(world.time < (last_move + move_delay))
return
last_move = world.time
step(parent, dir)

View File

@@ -107,6 +107,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list(
/client/proc/smite,
/client/proc/spawn_floor_cluwne, // Yogs
/client/proc/spawn_random_floor_cluwne,
/client/proc/spawn_twitch_plays_clowncar,
/client/proc/admin_away,
/client/proc/roll_dices //CIT CHANGE - Adds dice verb
))

View File

@@ -1,33 +0,0 @@
/client/proc/spawn_floor_cluwne()
set category = "Fun"
set name = "Unleash Targeted Floor Cluwne"
set desc = "Pick a specific target. Be warned: spawning more than one may cause issues!"
var/target
if(!check_rights(R_FUN))
return
target = input("Any specific target in mind? Please note only live, non cluwned, human targets are valid.", "Target", target) as null|anything in GLOB.player_list
if(target && ishuman(target))
var/mob/living/carbon/human/H = target
var/mob/living/simple_animal/hostile/floor_cluwne/FC = new /mob/living/simple_animal/hostile/floor_cluwne(H.loc)
FC.forced = TRUE
FC.Acquire_Victim(H)
FC.target = H
FC.current_victim = H
log_admin("[key_name(usr)] spawned floor cluwne.")
message_admins("[key_name(usr)] spawned floor cluwne.")
deadchat_broadcast("<span class='deadsay'><b>Floor Cluwne</b> has just been spawned!</span>")
/client/proc/spawn_random_floor_cluwne()
set category = "Fun"
set name = "Unleash Random Floor Cluwne"
set desc = "Goes after a random player in your Z level. Be warned: spawning more than one may cause issues!"
if(!check_rights(R_FUN))
return
var/turf/T = get_turf(usr)
new /mob/living/simple_animal/hostile/floor_cluwne(T)
log_admin("[key_name(usr)] spawned a random target floor cluwne.")
message_admins("[key_name(usr)] spawned a random target floor cluwne.")

View File

@@ -325,6 +325,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
ghostize(0, penalize = TRUE)
/mob/dead/observer/Move(NewLoc, direct, glide_size_override = 32)
if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_MOVE, NewLoc) & COMPONENT_MOVABLE_BLOCK_PRE_MOVE)
return
if(updatedir)
setDir(direct)//only update dir if we actually need it, so overlays won't spin on base sprites that don't have directions of their own
var/oldloc = loc

View File

@@ -127,4 +127,25 @@
icon_state = initial(icon_state)
/obj/vehicle/sealed/car/clowncar/proc/StopDroppingOil()
droppingoil = FALSE
droppingoil = FALSE
/obj/vehicle/sealed/car/clowncar/twitch_plays
key_type = null
/obj/vehicle/sealed/car/clowncar/twitch_plays/Initialize()
. = ..()
AddComponent(/datum/component/twitch_plays/simple_movement)
START_PROCESSING(SSfastprocess, src)
GLOB.poi_list |= src
notify_ghosts("Twitch Plays: Clown Car")
/obj/vehicle/sealed/car/clowncar/twitch_plays/Destroy()
STOP_PROCESSING(SSfastprocess, src)
GLOB.poi_list -= src
return ..()
/obj/vehicle/sealed/car/clowncar/twitch_plays/process()
var/dir = SEND_SIGNAL(src, COMSIG_TWITCH_PLAYS_MOVEMENT_DATA, TRUE)
if(!dir)
return
driver_move(null, dir)