[READY] Hark! The Medieval Reality Simulation Dome Emergency Shuttle! (+speech mutation, NOTELEPORT fixes and teambuilder improvements) (#55424)

* HARK! THERE ARE SOME MAIDENS THAT NEED SAVING!

* claymores, chairs

* mapmerge, price increase, no losing the flag, no teleporting in, other small stuff

* oldworld language, medieval mutation, reviews

* see desc for full changelog

huge improvements to how medieval speech feels, CTF now fully lit, json beautified, bugs squashed and more NOTELEPORT exploits also quashed. (I NEED TO UNDO THIS FOR ATOMIZATION)

* removes my fixes? also bugfixes and CTF separation

* dumb json mistake, starting work on reality simulators

* BOWS ARE BROOOOOOOOOOOOOOOOOKEN

* br

* getting closer to working

* well, mostly everything now.

* finally ready

* removes languages stuff as it is buggy and does not work, fixes more bugs, fixes more bugs, fixes more bugs

* conflict fix

* linting

* more lint

* bow buff, speech fix, TON of ctf fixes

* oh fuck year

* NO MORE INSTA DELETING CREW

* whoops

* review handled

* pooosh

* conflict fix
This commit is contained in:
tralezab
2021-01-05 00:49:53 -08:00
committed by GitHub
parent eafab791bd
commit 1fd0485206
28 changed files with 3223 additions and 64 deletions
File diff suppressed because it is too large Load Diff
+1
View File
@@ -28,6 +28,7 @@
#define SWEDISH /datum/mutation/human/swedish
#define CHAV /datum/mutation/human/chav
#define ELVIS /datum/mutation/human/elvis
#define MEDIEVAL /datum/mutation/human/medieval
#define RADIOACTIVE /datum/mutation/human/radioactive
#define GLOWY /datum/mutation/human/glow
#define ANTIGLOWY /datum/mutation/human/glow/anti
+2
View File
@@ -10,6 +10,7 @@
#define LANGUAGE_ABSORB "absorb"
#define LANGUAGE_APHASIA "aphasia"
#define LANGUAGE_CTF "ctf"
#define LANGUAGE_CULTIST "cultist"
#define LANGUAGE_CURATOR "curator"
#define LANGUAGE_GLAND "gland"
@@ -20,3 +21,4 @@
#define LANGUAGE_SOFTWARE "software"
#define LANGUAGE_STONER "stoner"
#define LANGUAGE_VOICECHANGE "voicechange"
+1
View File
@@ -89,4 +89,5 @@
//Shuttle unlocks
#define SHUTTLE_UNLOCK_ALIENTECH "abductor"
#define SHUTTLE_UNLOCK_BUBBLEGUM "bubblegum"
#define SHUTTLE_UNLOCK_MEDISIM "holodeck"
#define SHUTTLE_UNLOCK_NARNAR "narnar"
+1
View File
@@ -110,6 +110,7 @@
if(!isfloorturf(random_location))
continue
var/turf/open/floor/F = random_location
if(!F.air)
continue
+40
View File
@@ -208,3 +208,43 @@
..()
owner.remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_STONER)
owner.remove_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, LANGUAGE_STONER)
/datum/mutation/human/medieval
name = "Medieval"
desc = "A horrible mutation originating from the distant past, thought to have once been a common gene in all of old world Europe."
quality = MINOR_NEGATIVE
text_gain_indication = "<span class='notice'>You feel like seeking the holy grail!</span>"
text_lose_indication = "<span class='notice'>You no longer feel like seeking anything.</span>"
/datum/mutation/human/medieval/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech)
/datum/mutation/human/medieval/on_losing(mob/living/carbon/human/owner)
if(..())
return
UnregisterSignal(owner, COMSIG_MOB_SAY)
/datum/mutation/human/medieval/proc/handle_speech(datum/source, list/speech_args)
SIGNAL_HANDLER
var/message = speech_args[SPEECH_MESSAGE]
if(message)
message = " [message] "
var/list/medieval_words = strings("medieval_replacement.json", "medieval")
var/list/startings = strings("medieval_replacement.json", "startings")
for(var/key in medieval_words)
var/value = medieval_words[key]
if(islist(value))
value = pick(value)
if(uppertext(key) == key)
value = uppertext(value)
if(capitalize(key) == key)
value = capitalize(value)
message = replacetextEx(message,regex("\b[REGEX_QUOTE(key)]\b","ig"), value)
message = trim(message)
var/chosen_starting = pick(startings)
message = "[chosen_starting] [message]"
speech_args[SPEECH_MESSAGE] = message
+10
View File
@@ -235,6 +235,16 @@
admin_notes = "Due to the limited space for non paying crew, this shuttle may cause a riot."
credit_cost = CARGO_CRATE_VALUE * 20
/datum/map_template/shuttle/emergency/medisim
suffix = "medisim"
name = "Medieval Reality Simulation Dome"
description = "A state of the art simulation dome, loaded onto your shuttle! Watch and laugh at how petty humanity used to be before it reached the stars. Guaranteed to be at least 40% historically accurate."
admin_notes = "Ghosts can spawn in and fight as knights or archers. The CTF auto restarts, so no admin intervention necessary."
credit_cost = 20000
/datum/map_template/shuttle/emergency/medisim/prerequisites_met()
return SSshuttle.shuttle_purchase_requirements_met[SHUTTLE_UNLOCK_MEDISIM]
/datum/map_template/shuttle/emergency/discoinferno
suffix = "discoinferno"
name = "Disco Inferno"
+6
View File
@@ -144,6 +144,12 @@
name = "Luxurious Emergency Shuttle"
area_flags = NOTELEPORT
/area/shuttle/escape/simulation
name = "Medieval Reality Simulation Dome"
icon_state = "shuttlectf"
area_flags = NOTELEPORT
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
/area/shuttle/escape/arena
name = "The Arena"
area_flags = NOTELEPORT
+8 -6
View File
@@ -14,16 +14,20 @@
///What radio station is your radio set to when crossed (And human)?
var/team_radio = FREQ_COMMON
/obj/machinery/teambuilder/Initialize()
. = ..()
add_filter("teambuilder", 2, list("type" = "outline", "color" = team_color, "size" = 2))
/obj/machinery/teambuilder/examine_more(mob/user)
. = ..()
. += "<span class='notice'>You see a hastily written note on the side, it says '1215-1217, PICK A SIDE'.</span>"
/obj/machinery/teambuilder/Crossed(atom/movable/AM, oldloc)
. = ..()
if(AM.color)
if(AM.get_filter("teambuilder"))
return
if(isliving(AM) && team_color)
AM.color = team_color
AM.add_filter("teambuilder", 2, list("type" = "outline", "color" = team_color, "size" = 2))
if(ishuman(AM) && team_radio)
var/mob/living/carbon/human/human = AM
var/obj/item/radio/Radio = human.ears
@@ -34,13 +38,11 @@
/obj/machinery/teambuilder/red
name = "Teambuilding Machine (Red)"
desc = "A machine that, when passed, colors you based on the color of your team. Go red team!"
color = "#ff0000"
team_color = "#ff0000"
team_color = COLOR_RED
team_radio = FREQ_CTF_RED
/obj/machinery/teambuilder/blue
name = "Teambuilding Machine (Blue)"
desc = "A machine that, when passed, colors you based on the color of your team. Go blue team!"
color = "#0000ff"
team_color = "#0000ff"
team_color = COLOR_BLUE
team_radio = FREQ_CTF_BLUE
+4
View File
@@ -349,6 +349,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
if(anchored)
return
. = TRUE
if(resistance_flags & ON_FIRE)
var/mob/living/carbon/C = user
var/can_handle_hot = FALSE
@@ -392,10 +394,12 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
if(!allow_attack_hand_drop(user) || !user.temporarilyRemoveItemFromInventory(src))
return
. = FALSE
pickup(user)
add_fingerprint(user)
if(!user.put_in_active_hand(src, FALSE, FALSE))
user.dropItemToGround(src)
return TRUE
/obj/item/proc/allow_attack_hand_drop(mob/user)
return TRUE
+11 -1
View File
@@ -169,7 +169,6 @@
underlays += mutable_appearance('icons/obj/structures.dmi', "grille") //add a grille underlay
underlays += mutable_appearance('icons/turf/floors.dmi', "plating") //add the plating underlay, below the grille
/turf/closed/indestructible/opsglass
name = "window"
icon = 'icons/obj/smooth_structures/plastitanium_window.dmi'
@@ -240,6 +239,17 @@
underlay_appearance.icon_state = "necro1"
return TRUE
/turf/closed/indestructible/iron
name = "impervious metal wall"
desc = "A wall with tough metal plating."
icon = 'icons/turf/walls/iron_wall.dmi'
icon_state = "iron_wall-0"
base_icon_state = "iron_wall"
smoothing_flags = SMOOTH_BITMASK
smoothing_groups = list(SMOOTH_GROUP_CLOSED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_IRON_WALLS)
canSmoothWith = list(SMOOTH_GROUP_IRON_WALLS)
opacity = FALSE
/turf/closed/indestructible/riveted/boss
name = "necropolis wall"
desc = "A thick, seemingly indestructible stone wall."
+10
View File
@@ -188,3 +188,13 @@
/turf/open/floor/plating/rust/rust_heretic_act()
return
/turf/open/floor/stone
name = "stone brick floor"
desc = "Odd, really, how it looks exactly like the iron walls yet is stone instead of iron. Now, if that's really more of a complaint about\
the ironness of walls or the stoneness of the floors, that's really up to you. But have you really ever seen iron that dull? I mean, it\
makes sense for the station to have dull metal walls but we're talking how a rudimentary iron wall would be. Medieval ages didn't even\
use iron walls, iron walls are actually not even something that exists because iron is an expensive and not-so-great thing to build walls\
out of. It only makes sense in the context of space because you're trying to keep a freezing vacuum out. Is anyone following me on this? \
The idea of a \"rudimentary\" iron wall makes no sense at all! Is anything i'm even saying here true? Someone's gotta fact check this!"
icon_state = "stone_floor"
+1 -1
View File
@@ -2126,7 +2126,7 @@
else if(href_list["ctf_toggle"])
if(!check_rights(R_ADMIN))
return
toggle_all_ctf(usr)
toggle_id_ctf(usr, "centcom")
else if(href_list["rebootworld"])
if(!check_rights(R_ADMIN))
+1 -1
View File
@@ -152,7 +152,7 @@
dat += "</table>"
holder << browse(dat, "window=fingerprints;size=440x410")
if("ctfbutton")
toggle_all_ctf(holder)
toggle_id_ctf(holder, "centcom")
if("tdomereset")
var/delete_mobs = alert("Clear all mobs?","Confirm","Yes","No","Cancel")
if(delete_mobs == "Cancel")
+119 -55
View File
@@ -7,8 +7,6 @@
#define AMMO_DROP_LIFETIME 300
#define CTF_REQUIRED_PLAYERS 4
/obj/item/ctf
name = "banner"
icon = 'icons/obj/banner.dmi'
@@ -30,6 +28,8 @@
var/anyonecanpickup = TRUE
var/obj/effect/ctf/flag_reset/reset
var/reset_path = /obj/effect/ctf/flag_reset
/// Which area we announce updates on the flag to. Should just generally be the area of the arena.
var/game_area = /area/ctf
/obj/item/ctf/Destroy()
QDEL_NULL(reset)
@@ -39,24 +39,33 @@
. = ..()
if(!reset)
reset = new reset_path(get_turf(src))
RegisterSignal(src, COMSIG_PARENT_PREQDELETED, .proc/reset_flag) //just in case CTF has some map hazards (read: chasms).
/obj/item/ctf/ComponentInitialize()
. = ..()
AddComponent(/datum/component/two_handed)
AddComponent(/datum/component/two_handed, require_twohands = TRUE)
/obj/item/ctf/process()
if(is_ctf_target(loc)) //don't reset from someone's hands.
if(is_ctf_target(loc)) //pickup code calls temporary drops to test things out, we need to make sure the flag doesn't reset from
return PROCESS_KILL
if(world.time > reset_cooldown)
forceMove(get_turf(src.reset))
for(var/mob/M in GLOB.player_list)
var/area/mob_area = get_area(M)
if(istype(mob_area, /area/ctf))
to_chat(M, "<span class='userdanger'>\The [src] has been returned to base!</span>")
STOP_PROCESSING(SSobj, src)
reset_flag()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/ctf/proc/reset_flag(capture = FALSE)
SIGNAL_HANDLER
forceMove(get_turf(src.reset))
for(var/mob/M in GLOB.player_list)
var/area/mob_area = get_area(M)
if(istype(mob_area, game_area))
if(!capture)
to_chat(M, "<span class='userdanger'>[src] has been returned to the base!</span>")
STOP_PROCESSING(SSobj, src)
return TRUE //so if called by a signal, it doesn't delete
//working with attack hand feels like taking my brain and putting it through an industrial pill press so i'm gonna be a bit liberal with the comments
/obj/item/ctf/attack_hand(mob/living/user)
//pre normal check item stuff, this is for our special flag checks
if(!is_ctf_target(user) && !anyonecanpickup)
to_chat(user, "<span class='warning'>Non-players shouldn't be moving the flag!</span>")
return
@@ -66,30 +75,30 @@
if(loc == user)
if(!user.dropItemToGround(src))
return
anchored = FALSE
pickup(user)
if(!user.put_in_active_hand(src))
dropped(user)
return
user.set_anchored(TRUE)
user.status_flags &= ~CANPUSH
for(var/mob/M in GLOB.player_list)
var/area/mob_area = get_area(M)
if(istype(mob_area, /area/ctf))
to_chat(M, "<span class='userdanger'>\The [src] has been taken!</span>")
if(istype(mob_area, game_area))
to_chat(M, "<span class='userdanger'>\The [initial(src.name)] has been taken!</span>")
STOP_PROCESSING(SSobj, src)
..()
anchored = FALSE //normal checks need this to be FALSE to pass
. = ..() //this is the actual normal item checks
if(.) //only apply these flag passives
anchored = TRUE
return
//passing means the user picked up the flag so we can now apply this
user.set_anchored(TRUE)
user.status_flags &= ~CANPUSH
/obj/item/ctf/dropped(mob/user)
..()
user.set_anchored(FALSE)
user.status_flags |= CANPUSH
reset_cooldown = world.time + 200 //20 seconds
reset_cooldown = world.time + 20 SECONDS
START_PROCESSING(SSobj, src)
for(var/mob/M in GLOB.player_list)
var/area/mob_area = get_area(M)
if(istype(mob_area, /area/ctf))
to_chat(M, "<span class='userdanger'>\The [src] has been dropped!</span>")
if(istype(mob_area, game_area))
to_chat(M, "<span class='userdanger'>\The [initial(name)] has been dropped!</span>")
anchored = TRUE
@@ -129,16 +138,25 @@
desc = "This is where a blue banner used to play capture the flag \
would go."
/proc/toggle_all_ctf(mob/user)
/proc/toggle_id_ctf(user, activated_id, automated = FALSE)
var/ctf_enabled = FALSE
var/area/A
for(var/obj/machinery/capture_the_flag/CTF in GLOB.machines)
if(activated_id != CTF.game_id)
continue
ctf_enabled = CTF.toggle_ctf()
A = get_area(CTF)
for(var/obj/machinery/power/emitter/E in A)
E.active = ctf_enabled
message_admins("[key_name_admin(user)] has [ctf_enabled? "enabled" : "disabled"] CTF!")
notify_ghosts("CTF has been [ctf_enabled? "enabled" : "disabled"]!",'sound/effects/ghost2.ogg')
if(user)
message_admins("[key_name_admin(user)] has [ctf_enabled ? "enabled" : "disabled"] CTF!")
else if(automated)
message_admins("CTF has finished a round and automatically restarted.")
notify_ghosts("CTF has automatically restarted after a round finished in [A]!",'sound/effects/ghost2.ogg')
else
message_admins("The players have spoken! Voting has enabled CTF!")
if(!automated)
notify_ghosts("CTF has been [ctf_enabled? "enabled" : "disabled"] in [A]!",'sound/effects/ghost2.ogg')
/obj/machinery/capture_the_flag
name = "CTF Controller"
@@ -146,6 +164,9 @@
icon = 'icons/obj/device.dmi'
icon_state = "syndbeacon"
resistance_flags = INDESTRUCTIBLE
var/game_id = "centcom"
var/victory_rejoin_text = "<span class='userdanger'>Teams have been cleared. Click on the machines to vote to begin another round.</span>"
var/team = WHITE_TEAM
var/team_span = ""
//Capture the Flag scoring
@@ -156,16 +177,20 @@
var/control_points = 0
var/control_points_to_win = 180
var/list/team_members = list()
///assoc list: mob = outfit datum (class)
var/list/spawned_mobs = list()
var/list/recently_dead_ckeys = list()
var/ctf_enabled = FALSE
var/ctf_gear = /datum/outfit/ctf
///assoc list for classes. If there's only one, it'll just equip. Otherwise, it lets you pick which outfit!
var/list/ctf_gear = list("white" = /datum/outfit/ctf)
var/instagib_gear = /datum/outfit/ctf/instagib
var/ammo_type = /obj/effect/ctf/ammo
var/list/dead_barricades = list()
var/static/arena_reset = FALSE
var/static/list/people_who_want_to_play = list()
var/game_area = /area/ctf
/obj/machinery/capture_the_flag/Initialize()
. = ..()
@@ -191,7 +216,7 @@
icon_state = "syndbeacon"
team = RED_TEAM
team_span = "redteamradio"
ctf_gear = /datum/outfit/ctf/red
ctf_gear = list("red" = /datum/outfit/ctf/red)
instagib_gear = /datum/outfit/ctf/red/instagib
/obj/machinery/capture_the_flag/blue
@@ -199,28 +224,32 @@
icon_state = "bluebeacon"
team = BLUE_TEAM
team_span = "blueteamradio"
ctf_gear = /datum/outfit/ctf/blue
ctf_gear = list("blue" = /datum/outfit/ctf/blue)
instagib_gear = /datum/outfit/ctf/blue/instagib
//ATTACK GHOST IGNORING PARENT RETURN VALUE
/obj/machinery/capture_the_flag/attack_ghost(mob/user)
if(ctf_enabled == FALSE)
if(user.client && user.client.holder)
var/response = alert("Enable CTF?", "CTF", "Yes", "No")
var/response = alert("Enable this CTF game?", "CTF", "Yes", "No")
if(response == "Yes")
toggle_all_ctf(user)
toggle_id_ctf(user, game_id)
return
if(!(GLOB.ghost_role_flags & GHOSTROLE_MINIGAME))
to_chat(user, "<span class='warning'>CTF has been temporarily disabled by admins.</span>")
return
for(var/obj/machinery/capture_the_flag/CTF in GLOB.machines)
if(CTF.game_id != game_id && CTF.ctf_enabled)
to_chat(user, "<span class='warning'>There is already an ongoing game in the [get_area(CTF)]!</span>")
return
people_who_want_to_play |= user.ckey
var/num = people_who_want_to_play.len
var/remaining = CTF_REQUIRED_PLAYERS - num
if(remaining <= 0)
people_who_want_to_play.Cut()
toggle_all_ctf()
toggle_id_ctf(null, game_id)
else
to_chat(user, "<span class='notice'>CTF has been requested. [num]/[CTF_REQUIRED_PLAYERS] have readied up.</span>")
@@ -239,7 +268,7 @@
return
for(var/obj/machinery/capture_the_flag/CTF in GLOB.machines)
if(CTF == src || CTF.ctf_enabled == FALSE)
if(CTF.game_id != game_id || CTF == src || CTF.ctf_enabled == FALSE)
continue
if(user.ckey in CTF.team_members)
to_chat(user, "<span class='warning'>No switching teams while the round is going!</span>")
@@ -247,31 +276,55 @@
if(CTF.team_members.len < src.team_members.len)
to_chat(user, "<span class='warning'>[src.team] has more team members than [CTF.team]! Try joining [CTF.team] team to even things up.</span>")
return
team_members |= user.ckey
var/client/new_team_member = user.client
if(user.mind && user.mind.current)
ctf_dust_old(user.mind.current)
spawn_team_member(new_team_member)
//does not add to recently dead, because it dusts and that triggers ctf_qdelled_player
/obj/machinery/capture_the_flag/proc/ctf_dust_old(mob/living/body)
if(isliving(body) && (team in body.faction))
var/turf/T = get_turf(body)
new /obj/effect/ctf/ammo(T)
recently_dead_ckeys += body.ckey
addtimer(CALLBACK(src, .proc/clear_cooldown, body.ckey), respawn_cooldown, TIMER_UNIQUE)
if(ammo_type)
new ammo_type(T)
body.dust()
/obj/machinery/capture_the_flag/proc/ctf_qdelled_player(mob/living/body)
SIGNAL_HANDLER
recently_dead_ckeys += body.ckey
addtimer(CALLBACK(src, .proc/clear_cooldown, body.ckey), respawn_cooldown, TIMER_UNIQUE)
/obj/machinery/capture_the_flag/proc/clear_cooldown(ckey)
recently_dead_ckeys -= ckey
/obj/machinery/capture_the_flag/proc/spawn_team_member(client/new_team_member)
var/mob/living/carbon/human/M = new/mob/living/carbon/human(get_turf(src))
var/datum/outfit/chosen_class
if(ctf_gear.len == 1) //no choices to make
for(var/key in ctf_gear)
chosen_class = ctf_gear[key]
else if(ctf_gear.len > 3) //a lot of choices, so much that we can't use a basic alert
var/result = input(new_team_member, "Select a class.", "CTF") as null|anything in sortList(ctf_gear)
if(!result || !(GLOB.ghost_role_flags & GHOSTROLE_MINIGAME) || (new_team_member.ckey in recently_dead_ckeys) || !isobserver(new_team_member.mob))
return //picked nothing, admin disabled it, cheating to respawn faster, cheating to respawn... while in game?
chosen_class = ctf_gear[result]
else //2-3 choices
var/list/names_only = assoc_list_strip_value(ctf_gear)
names_only.len += 1 //create a new null entry so if it's a 2-sized list, names_only[3] is null instead of out of bounds
var/result = alert(new_team_member, "Select a class.", "CTF", names_only[1], names_only[2], names_only[3])
if(!result || !(GLOB.ghost_role_flags & GHOSTROLE_MINIGAME) || (new_team_member.ckey in recently_dead_ckeys) || !isobserver(new_team_member.mob))
return //picked nothing, admin disabled it, cheating to respawn faster, cheating to respawn... while in game?
chosen_class = ctf_gear[result]
var/mob/living/carbon/human/M = new /mob/living/carbon/human(get_turf(src))
new_team_member.prefs.copy_to(M)
M.set_species(/datum/species/synth)
M.key = new_team_member.key
M.faction += team
M.equipOutfit(ctf_gear)
spawned_mobs += M
M.equipOutfit(chosen_class)
RegisterSignal(M, COMSIG_PARENT_QDELETING, .proc/ctf_qdelled_player) //just in case CTF has some map hazards (read: chasms). bit shorter than dust
spawned_mobs[M] = chosen_class
team_members |= new_team_member.ckey
return M //used in medisim.dm
/obj/machinery/capture_the_flag/Topic(href, href_list)
if(href_list["join"])
@@ -283,22 +336,22 @@
if(istype(I, /obj/item/ctf))
var/obj/item/ctf/flag = I
if(flag.team != src.team)
user.transferItemToLoc(flag, get_turf(flag.reset), TRUE)
points++
for(var/mob/M in GLOB.player_list)
var/area/mob_area = get_area(M)
if(istype(mob_area, /area/ctf))
to_chat(M, "<span class='userdanger [team_span]'>[user.real_name] has captured \the [flag], scoring a point for [team] team! They now have [points]/[points_to_win] points!</span>")
if(points >= points_to_win)
victory()
flag.reset_flag(capture = TRUE)
for(var/mob/ctf_player in GLOB.player_list)
var/area/mob_area = get_area(ctf_player)
if(istype(mob_area, game_area))
to_chat(ctf_player, "<span class='userdanger [team_span]'>[user.real_name] has captured \the [flag], scoring a point for [team] team! They now have [points]/[points_to_win] points!</span>")
if(points >= points_to_win)
victory()
/obj/machinery/capture_the_flag/proc/victory()
for(var/mob/_competitor in GLOB.mob_living_list)
var/mob/living/competitor = _competitor
var/area/mob_area = get_area(competitor)
if(istype(mob_area, /area/ctf))
if(istype(mob_area, game_area))
to_chat(competitor, "<span class='narsie [team_span]'>[team] team wins!</span>")
to_chat(competitor, "<span class='userdanger'>Teams have been cleared. Click on the machines to vote to begin another round.</span>")
to_chat(competitor, victory_rejoin_text)
for(var/obj/item/ctf/W in competitor)
competitor.dropItemToGround(W)
competitor.dust()
@@ -306,6 +359,8 @@
control.icon_state = "dominator"
control.controlling = null
for(var/obj/machinery/capture_the_flag/CTF in GLOB.machines)
if(CTF.game_id != game_id)
continue
if(CTF.ctf_enabled == TRUE)
CTF.points = 0
CTF.control_points = 0
@@ -366,12 +421,16 @@
/obj/machinery/capture_the_flag/proc/instagib_mode()
for(var/obj/machinery/capture_the_flag/CTF in GLOB.machines)
if(CTF.game_id != game_id)
continue
if(CTF.ctf_enabled == TRUE)
CTF.ctf_gear = CTF.instagib_gear
CTF.respawn_cooldown = INSTAGIB_RESPAWN
/obj/machinery/capture_the_flag/proc/normal_mode()
for(var/obj/machinery/capture_the_flag/CTF in GLOB.machines)
if(CTF.game_id != game_id)
continue
if(CTF.ctf_enabled == TRUE)
CTF.ctf_gear = initial(ctf_gear)
CTF.respawn_cooldown = DEFAULT_RESPAWN
@@ -447,8 +506,10 @@
. = TRUE
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/shielded/ctf))
. = TRUE
for(var/obj/machinery/capture_the_flag/CTF in GLOB.machines)
if(H in CTF.spawned_mobs)
. = TRUE
break
// RED TEAM GUNS
@@ -633,7 +694,7 @@
return
for(var/obj/machinery/capture_the_flag/CTF in GLOB.machines)
if(M in CTF.spawned_mobs)
var/outfit = CTF.ctf_gear
var/outfit = CTF.spawned_mobs[M]
var/datum/outfit/O = new outfit
for(var/obj/item/gun/G in M)
qdel(G)
@@ -648,10 +709,13 @@
desc = "It provided cover in fire fights. And now it's gone."
icon = 'icons/obj/objects.dmi'
icon_state = "barrier0"
var/game_id = "centcom"
/obj/effect/ctf/dead_barricade/Initialize(mapload)
. = ..()
for(var/obj/machinery/capture_the_flag/CTF in GLOB.machines)
if(CTF.game_id != game_id)
continue
CTF.dead_barricades += src
/obj/effect/ctf/dead_barricade/proc/respawn()
@@ -659,7 +723,6 @@
new /obj/structure/barricade/security/ctf(get_turf(src))
qdel(src)
//Control Point
/obj/machinery/control_point
@@ -671,6 +734,7 @@
var/obj/machinery/capture_the_flag/controlling
var/team = "none"
var/point_rate = 0.5
var/game_area = /area/ctf
/obj/machinery/control_point/process(delta_time)
if(controlling)
@@ -695,7 +759,7 @@
icon_state = "dominator-[CTF.team]"
for(var/mob/M in GLOB.player_list)
var/area/mob_area = get_area(M)
if(istype(mob_area, /area/ctf))
if(istype(mob_area, game_area))
to_chat(M, "<span class='userdanger'>[user.real_name] has captured \the [src], claiming it for [CTF.team]! Go take it back!</span>")
break
+6
View File
@@ -43,6 +43,12 @@
inhand_icon_state = "blueshift"
custom_premium_price = PAYCHECK_HARD
/obj/item/clothing/suit/armor/vest/cuirass
name = "cuirass"
desc = "A lighter plate armor used to still keep out those pesky arrows, while retaining the ability to move."
icon_state = "cuirass"
inhand_icon_state = "armor"
/obj/item/clothing/suit/armor/hos
name = "armored greatcoat"
desc = "A greatcoat enhanced with a special alloy for some extra protection and style for those with a commanding presence."
+3
View File
@@ -288,6 +288,9 @@
M.flags_1 |= NODECONSTRUCT_1
for(var/obj/structure/S in added)
S.flags_1 |= NODECONSTRUCT_1
if(istype(program, /area/holodeck/rec_center/thunderdome1218) && !SSshuttle.shuttle_purchase_requirements_met[SHUTTLE_UNLOCK_MEDISIM])
say("Special note from \"1218 AD\" developer: I see you too are interested in the REAL dark ages of humanity! I've made this program also unlock some interesting shuttle designs on any communication console around. Have fun!")
SSshuttle.shuttle_purchase_requirements_met[SHUTTLE_UNLOCK_MEDISIM] = TRUE
/obj/machinery/computer/holodeck/proc/derez(obj/O, silent = TRUE, forced = FALSE)
// Emagging a machine creates an anomaly in the derez systems.
@@ -145,6 +145,10 @@
. = ..()
AddComponent(/datum/component/caltrop, 20, 30, 100, CALTROP_BYPASS_SHOES)
/obj/structure/punji_sticks/spikes
name = "wooden spikes"
icon_state = "woodspike"
/////////BONFIRES//////////
/obj/structure/bonfire
+125
View File
@@ -0,0 +1,125 @@
/obj/item/gun/ballistic/bow
name = "longbow"
desc = "While pretty finely crafted, surely you can find something better to use in the current year."
icon = 'icons/obj/guns/projectile.dmi'
icon_state = "bow"
inhand_icon_state = "bow"
load_sound = null
fire_sound = null
mag_type = /obj/item/ammo_box/magazine/internal/bow
force = 15
attack_verb_continuous = list("whipped", "cracked")
attack_verb_simple = list("whip", "crack")
weapon_weight = WEAPON_HEAVY
w_class = WEIGHT_CLASS_BULKY
internal_magazine = TRUE
bolt_type = BOLT_TYPE_NO_BOLT
var/drawn = FALSE
/obj/item/gun/ballistic/bow/update_icon()
. = ..()
if(!chambered)
icon_state = "bow"
else
icon_state = "bow_[drawn]"
/obj/item/gun/ballistic/bow/proc/drop_arrow()
drawn = FALSE
if(!chambered)
chambered = magazine.get_round(keep = FALSE)
return
if(!chambered)
return
chambered.forceMove(drop_location())
update_icon()
/obj/item/gun/ballistic/bow/chamber_round(keep_bullet = FALSE, spin_cylinder, replace_new_round)
if(chambered || !magazine)
return
if(magazine.ammo_count())
chambered = magazine.get_round(TRUE)
chambered.forceMove(src)
/obj/item/gun/ballistic/bow/attack_self(mob/user)
if(chambered)
to_chat(user, "<span class='notice'>You [drawn ? "release the tension on" : "draw the string on"] [src].</span>")
drawn = !drawn
update_icon()
/obj/item/gun/ballistic/bow/afterattack(atom/target, mob/living/user, flag, params, passthrough = FALSE)
if(!chambered)
return
if(!drawn)
to_chat(user, "<span clasas='warning'>Without drawing the bow, the arrow uselessly falls to the ground.</span>")
drop_arrow()
update_icon()
return
drawn = FALSE
. = ..() //fires, removing the arrow
update_icon()
/obj/item/gun/ballistic/bow/shoot_with_empty_chamber(mob/living/user)
return //so clicking sounds please
/obj/item/ammo_box/magazine/internal/bow
name = "bowstring"
ammo_type = /obj/item/ammo_casing/caseless/arrow
max_ammo = 1
start_empty = TRUE
caliber = "arrow"
/obj/item/ammo_casing/caseless/arrow
name = "arrow"
desc = "Stabby Stabman!"
icon_state = "arrow"
flags_1 = NONE
throwforce = 1
projectile_type = /obj/projectile/bullet/reusable/arrow
firing_effect_type = null
caliber = "arrow"
heavy_metal = FALSE
/obj/item/ammo_casing/caseless/arrow/despawning/dropped()
. = ..()
addtimer(CALLBACK(src, .proc/floor_vanish), 5 SECONDS)
/obj/item/ammo_casing/caseless/arrow/despawning/proc/floor_vanish()
if(isturf(loc))
qdel(src)
/obj/projectile/bullet/reusable/arrow
name = "arrow"
desc = "Ow! Get it out of me!"
ammo_type = /obj/item/ammo_casing/caseless/arrow
damage = 50
speed = 1
range = 25
/obj/item/storage/bag/quiver
name = "quiver"
desc = "Holds arrows for your bow. Good, because while pocketing arrows is possible, it surely can't be pleasant."
icon_state = "quiver"
inhand_icon_state = "quiver"
worn_icon_state = "harpoon_quiver"
var/arrow_path = /obj/item/ammo_casing/caseless/arrow
/obj/item/storage/bag/quiver/Initialize(mapload)
. = ..()
var/datum/component/storage/storage = GetComponent(/datum/component/storage)
storage.max_w_class = WEIGHT_CLASS_TINY
storage.max_items = 40
storage.max_combined_w_class = 100
storage.set_holdable(list(
/obj/item/ammo_casing/caseless/arrow
))
/obj/item/storage/bag/quiver/PopulateContents()
. = ..()
for(var/i in 1 to 10)
new arrow_path(src)
/obj/item/storage/bag/quiver/despawning
arrow_path = /obj/item/ammo_casing/caseless/arrow/despawning
+144
View File
@@ -0,0 +1,144 @@
///These are for the medisim shuttle
#define REDFIELD_TEAM "Red"
#define BLUESWORTH_TEAM "Blue"
/obj/machinery/capture_the_flag/medisim
game_id = "medieval"
game_area = /area/shuttle/escape/simulation
ammo_type = null //no guns, no need
victory_rejoin_text = "<span class='userdanger'>Teams have been cleared. The next game is starting automatically. Rejoin a team if you wish!</span>"
/obj/machinery/capture_the_flag/medisim/Initialize(mapload)
. = ..()
start_ctf() //both machines initialize, so both will call start_ctf instead of toggle_id_ctf calling it for both, twice.
/obj/machinery/capture_the_flag/medisim/victory()
. = ..()
toggle_id_ctf(null, game_id, automated = TRUE)//only one machine runs the victory proc, start_ctf proc would break the other machine
/obj/machinery/capture_the_flag/medisim/spawn_team_member(client/new_team_member)
. = ..()
if(!.)
return
var/mob/living/carbon/human/human_knight = .
randomize_human(human_knight)
human_knight.dna.add_mutation(MEDIEVAL, MUT_OTHER)
var/oldname = human_knight.name
var/title = "error"
switch (human_knight.gender)
if (MALE)
title = pick(list("Sir", "Lord"))
if (FEMALE)
title = pick(list("Dame", "Lady"))
else
title = "Noble"
human_knight.real_name = "[title] [oldname]"
human_knight.name = human_knight.real_name
/obj/machinery/capture_the_flag/medisim/red
name = "\improper Redfield Data Realizer"
icon_state = "syndbeacon"
team = REDFIELD_TEAM
team_span = "redteamradio"
ctf_gear = list("knight" = /datum/outfit/medisim/red_knight, "archer" = /datum/outfit/medisim/red_archer)
/obj/machinery/capture_the_flag/medisim/blue
name = "\improper Bluesworth Data Realizer"
icon_state = "bluebeacon"
team = BLUESWORTH_TEAM
team_span = "blueteamradio"
ctf_gear = list("knight" = /datum/outfit/medisim/blue_knight, "archer" = /datum/outfit/medisim/blue_archer)
/obj/item/ctf/red/medisim
name = "\improper Redfield Castle Fair Maiden"
desc = "Protect your maiden, and capture theirs!"
icon = 'icons/obj/plushes.dmi'
icon_state = "plushie_nuke"
game_area = /area/shuttle/escape
movement_type = FLOATING //there are chasms, and resetting when they fall in is really lame so lets minimize that
/obj/item/ctf/blue/medisim
name = "\improper Bluesworth Hold Fair Maiden"
desc = "Protect your maiden, and capture theirs!"
icon = 'icons/obj/plushes.dmi'
icon_state = "plushie_slime"
game_area = /area/shuttle/escape
movement_type = FLOATING //there are chasms, and resetting when they fall in is really lame so lets minimize that
//everything except arrows
/datum/outfit/medisim/post_equip(mob/living/carbon/human/H, visualsOnly)
var/list/no_drops = list()
no_drops += H.get_item_by_slot(ITEM_SLOT_FEET)
no_drops += H.get_item_by_slot(ITEM_SLOT_BELT)
no_drops += H.get_item_by_slot(ITEM_SLOT_ICLOTHING)
no_drops += H.get_item_by_slot(ITEM_SLOT_OCLOTHING)
no_drops += H.get_item_by_slot(ITEM_SLOT_HEAD)
no_drops += H.get_item_by_slot(ITEM_SLOT_HANDS)
no_drops += H.get_item_by_slot(ITEM_SLOT_GLOVES)
listclearnulls(no_drops) //any slots we didn't have
for(var/_outfit_item in no_drops)
var/obj/item/outfit_item = _outfit_item
outfit_item.item_flags |= DROPDEL//so this all stays clean :)
/datum/outfit/medisim/red_knight
name = "Redfield Castle Knight"
uniform = /obj/item/clothing/under/color/red
shoes = /obj/item/clothing/shoes/plate/red
suit = /obj/item/clothing/suit/armor/riot/knight/red
gloves = /obj/item/clothing/gloves/plate/red
head = /obj/item/clothing/head/helmet/knight/red
r_hand = /obj/item/claymore
/datum/outfit/medisim/blue_knight
name = "Bluesworth Hold Knight"
uniform = /obj/item/clothing/under/color/blue
shoes = /obj/item/clothing/shoes/plate/blue
suit = /obj/item/clothing/suit/armor/riot/knight/blue
gloves = /obj/item/clothing/gloves/plate/blue
head = /obj/item/clothing/head/helmet/knight/blue
r_hand = /obj/item/claymore
/datum/outfit/medisim/red_archer
name = "Redfield Castle Archer"
uniform = /obj/item/clothing/under/color/red
belt = /obj/item/storage/bag/quiver
shoes = /obj/item/clothing/shoes/plate/red
suit = /obj/item/clothing/suit/armor/vest/cuirass
gloves = /obj/item/clothing/gloves/plate/red
head = /obj/item/clothing/head/helmet/knight/red
r_hand = /obj/item/gun/ballistic/bow
/datum/outfit/medisim/blue_archer
name = "Bluesworth Hold Archer"
uniform = /obj/item/clothing/under/color/blue
belt = /obj/item/storage/bag/quiver
shoes = /obj/item/clothing/shoes/plate/blue
suit = /obj/item/clothing/suit/armor/vest/cuirass
gloves = /obj/item/clothing/gloves/plate/blue
head = /obj/item/clothing/head/helmet/knight/blue
r_hand = /obj/item/gun/ballistic/bow
/obj/machinery/computer/reality_simulation
name = "reality simulation computer"
desc = "A computer calculating the medieval times. Uh, wow. Is this bad boy quantum?"
/obj/item/paper/crumpled/retired_designs
name = "crumpled notes on cuirass design"
info = {"Yeah, you may as well just melt this crap back down into metal.<br>
<br>
<br>
What else am I supposed to say? Nanotrasen thinks these authentic cuirass models are too expensive for the simulation watchers.
That's bullshit, but my hands are tied. But you know. If one of you cargo folk up at central command take a cuirass for yourself
instead of throwing the damn thing out, like, I'm sure nobody would notice or care. OK, but I'm sitting here on an official
NT shuttle encouraging you to break spacelaw. Damn, I'm bored as fuck. I was kidding. Melt em. See you guys soon.
<br>
<br>
<i>the rest of the page is filled with various doodles of people fighting with swords.</i>"}
#undef REDFIELD_TEAM
#undef BLUESWORTH_TEAM
Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 KiB

After

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 KiB

After

Width:  |  Height:  |  Size: 362 KiB

+323
View File
@@ -0,0 +1,323 @@
{
"startings": [
"Forsooth,",
"I say,",
"I sayeth,",
"Forsooth, I say,",
"Forsooth, say I,",
"Forsooth, sayeth I,",
"Hark,",
"Harketh,",
"Avast,",
"Zounds,",
"Perchance,",
"Pray tell,",
"Prithee,",
"What hey,",
"What ho,",
"Pray,",
"Surely",
"Pray pardon,",
"Alas,",
"In short,",
"By my faith,",
"If it pleases you,",
"I pray you,",
"In truth,",
"By my trowth,",
"In sooth,",
"By my word,",
"S'wounds,",
"Z'wounds,",
"Heigh-ho,",
"Ah,",
"Quoth I,",
"Listen,",
"Listen thee,",
"Hear me,",
"Now hear me,",
"I warrant",
"Come,",
"Kind sire,",
"Sire,",
"There is much in what you say, and yet,"
],
"medieval": {
"it is": "'tis",
"it's": "'tis",
"it was": "'twas",
"it will": "'twould",
"it were": "'twere",
"there": "thither",
"shall not": "shan't",
"will not": "shan't",
"over there": "yonder",
"in the": "i' the",
"thank you": [
"many good thanks to you",
"thankee",
"kindly thanks to you",
"grammercy to you"
],
"thanks": [
"many good thanks to you",
"thankee",
"kindly thanks to you",
"grammercy to you"
],
"you": [
"thou",
"thee",
"ye"
],
"your": [
"thine",
"thy",
"thyne"
],
"are": "art",
"killed": [
"slain",
"vanquished",
"brung low",
"conquered",
"fleeced",
"humbled",
"subjugated",
"bested",
"foiled"
],
"kill": [
"slay",
"vanquish",
"bring low",
"conquer",
"fleece",
"humble",
"subjugate",
"best",
"foil"
],
"goodbye": [
"farewell",
"fare thee well",
"good morrow",
"godspeed",
"begone",
"by your leave",
"good day",
"adieu",
"cheerio",
"pleasant journey",
"I bid thee good day",
"I bid thee farewell"
],
"bye": [
"farewell",
"fare thee well",
"good morrow",
"godspeed",
"begone",
"by your leave",
"good day",
"adieu",
"cheerio",
"pleasant journey",
"I bid thee good day",
"I bid thee farewell"
],
"yes": [
"aye",
"yea",
"yea verily"
],
"no": [
"nay",
"nayeth"
],
"hello": [
"hail",
"good day",
"well met",
"well meteth",
"tally ho",
"ave"
],
"hi": [
"hail",
"good day",
"well met",
"well meteth",
"tally ho",
"ave"
],
"does": [
"doeseth",
"dost",
"doth"
],
"my": "mine",
"in": "within",
"nuke disk": "plate of holy fire",
"captain": "king",
"cap": "king",
"food": [
"bellytimber",
"game",
"cake"
],
"going": "a-walkin'",
"go": "a-walk",
"bet": "warrant",
"the": "yon",
"kidding": [
"but pulling a jest",
"but pulling a jape"
],
"joke": [
"jest",
"jape"
],
"station": "castle",
"please": [
"I pray you",
"prithee",
"pray"
],
"ok": [
"as you will",
"agreed",
"well said",
"just so"
],
"is": "be",
"never": "ne'er",
"haha": [
"guffaw!",
"cackle!",
"oh, 'tis to laugh!",
"zounds!",
"chuckle!",
"snigger!",
"snicker!",
"snort!",
"cachinnate!",
"titter!",
"and there was much tittering!",
"and there was much guffawing!",
"and there was much chuckling!",
"and there was much snorting!",
"and there was much snickering!",
"and there was much mirth!"
],
"hehe": [
"guffaw!",
"cackle!",
"oh, 'tis to laugh!",
"zounds!",
"chuckle!",
"snigger!",
"snicker!",
"snort!",
"cachinnate!",
"titter!",
"and there was much tittering!",
"and there was much guffawing!",
"and there was much chuckling!",
"and there was much snorting!",
"and there was much snickering!",
"and there was much mirth!"
],
"hah": [
"guffaw!",
"cackle!",
"oh, 'tis to laugh!",
"zounds!",
"chuckle!",
"snigger!",
"snicker!",
"snort!",
"cachinnate!",
"titter!",
"and there was much tittering!",
"and there was much guffawing!",
"and there was much chuckling!",
"and there was much snorting!",
"and there was much snickering!",
"and there was much mirth!"
],
"heh": [
"guffaw!",
"cackle!",
"oh, 'tis to laugh!",
"zounds!",
"chuckle!",
"snigger!",
"snicker!",
"snort!",
"cachinnate!",
"titter!",
"and there was much tittering!",
"and there was much guffawing!",
"and there was much chuckling!",
"and there was much snorting!",
"and there was much snickering!",
"and there was much mirth!"
],
"help": [
"aid",
"aideth",
"saveth",
"assistance",
"succor"
],
"could": "couldst",
"would": "wouldst",
"sure": "shore",
"maybe": [
"mayhaps",
"perchance"
],
"probably": [
"mayhaps",
"perchance"
],
"girl": [
"madame",
"waif",
"mistress",
"lass",
"lady",
"maid",
"maiden"
],
"felinid": "catbeast",
"cat": "beast",
"moth": "gnat",
"mothperson": "gnat critter",
"plasmaman": "fire spirit",
"plasmamen": "fire spirits",
"lizard": "beast",
"lizardperson": "moat creature",
"soon": "anon",
"later": "anon",
"often": "oft",
"really": [
"indeed",
"in truth"
],
"those": "yon",
"here": "hither",
"enough": "ynogh",
"why": "wherefore",
"away": "aroint",
"being": "bein",
"of": "o'",
"shit": "nightsoil",
"fuck": "flummery",
"based": [
"joly",
"jolyf"
]
}
}
+2
View File
@@ -2815,6 +2815,7 @@
#include "code\modules\projectiles\guns\magic\wand.dm"
#include "code\modules\projectiles\guns\misc\beam_rifle.dm"
#include "code\modules\projectiles\guns\misc\blastcannon.dm"
#include "code\modules\projectiles\guns\misc\bow.dm"
#include "code\modules\projectiles\guns\misc\chem_gun.dm"
#include "code\modules\projectiles\guns\misc\grenade_launcher.dm"
#include "code\modules\projectiles\guns\misc\medbeam.dm"
@@ -3051,6 +3052,7 @@
#include "code\modules\shuttle\emergency.dm"
#include "code\modules\shuttle\ferry.dm"
#include "code\modules\shuttle\manipulator.dm"
#include "code\modules\shuttle\medisim.dm"
#include "code\modules\shuttle\monastery.dm"
#include "code\modules\shuttle\navigation_computer.dm"
#include "code\modules\shuttle\on_move.dm"