Resolving bugs with spawn order and delays.

This commit is contained in:
Zuhayr
2015-03-18 12:02:02 +10:30
parent d8018db5c9
commit a8f44cae98
24 changed files with 5545 additions and 5767 deletions

View File

@@ -1204,7 +1204,6 @@
#include "code\modules\mob\living\silicon\robot\robot_items.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules.dm"
#include "code\modules\mob\living\silicon\robot\robot_movement.dm"
#include "code\modules\mob\living\silicon\robot\subsystems.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_abilities.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_console.dm"

View File

@@ -1,45 +1,3 @@
var/global/list/all_antag_types = list()
var/global/list/all_antag_spawnpoints = list()
var/global/list/antag_names_to_ids = list()
/proc/get_antag_data(var/antag_type)
if(all_antag_types[antag_type])
return all_antag_types[antag_type]
else
for(var/cur_antag_type in all_antag_types)
var/datum/antagonist/antag = all_antag_types[cur_antag_type]
if(antag && antag.is_type(antag_type))
return antag
/proc/clear_antag_roles(var/datum/mind/player, var/implanted)
for(var/antag_type in all_antag_types)
var/datum/antagonist/antag = all_antag_types[antag_type]
if(!implanted || !(antag.flags & ANTAG_IMPLANT_IMMUNE))
antag.remove_antagonist(player, 1, implanted)
/proc/update_antag_icons(var/datum/mind/player)
for(var/antag_type in all_antag_types)
var/datum/antagonist/antag = all_antag_types[antag_type]
if(player)
antag.update_icons_removed(player)
if(antag.is_antagonist(player))
antag.update_icons_added(player)
else
antag.update_all_icons()
/proc/populate_antag_type_list()
for(var/antag_type in typesof(/datum/antagonist)-/datum/antagonist)
var/datum/antagonist/A = new antag_type
all_antag_types[A.id] = A
all_antag_spawnpoints[A.landmark_id] = list()
antag_names_to_ids[A.role_text] = A.id
/proc/get_antags(var/atype)
var/datum/antagonist/antag = all_antag_types[atype]
if(antag && islist(antag.current_antagonists))
return antag.current_antagonists
return list()
/datum/antagonist
var/role_type = BE_TRAITOR
@@ -51,8 +9,6 @@ var/global/list/antag_names_to_ids = list()
var/loss_text
var/victory_feedback_tag
var/loss_feedback_tag
var/spawn_upper = 5
var/spawn_lower = 3
var/max_antags = 3
var/max_antags_round = 5
@@ -73,9 +29,10 @@ var/global/list/antag_names_to_ids = list()
var/cur_max = 0
var/datum/mind/leader
var/spawned_nuke
var/nuke_spawn_loc
var/list/valid_species = list("Unathi","Tajara","Skrell","Human") // Used for setting appearance.
var/list/starting_locations = list()
var/list/current_antagonists = list()
var/list/global_objectives = list()
@@ -83,48 +40,19 @@ var/global/list/antag_names_to_ids = list()
var/list/protected_jobs = list()
var/list/candidates = list()
var/default_access = list()
var/id_type = /obj/item/weapon/card/id
/datum/antagonist/New()
..()
cur_max = max_antags
get_starting_locations()
if(config.protect_roles_from_antagonist)
restricted_jobs |= protected_jobs
/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player, var/move_to_spawn)
var/main_type
if(ticker && ticker.mode)
if(ticker.mode.antag_tag && ticker.mode.antag_tag == id)
main_type = 1
else
return 0
var/cur_max = (main_type ? max_antags_round : max_antags)
if(ticker.mode.antag_scaling_coeff)
cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max)
if(get_antag_count() > cur_max-1)
return 0
player.current << "<span class='danger'><i>You have been selected this round as an antagonist!</i></span>"
add_antagonist(player)
equip(player.current)
finalize(player)
if(move_to_spawn)
place_mob(player.current)
return
/datum/antagonist/proc/tick()
return 1
/datum/antagonist/proc/is_antagonist(var/datum/mind/player)
if(player in current_antagonists)
return 1
/datum/antagonist/proc/is_type(var/antag_type)
if(antag_type == id || antag_type == role_text)
return 1
return 0
/datum/antagonist/proc/get_panel_entry(var/datum/mind/player)
var/dat = "<tr><td><b>[role_text]:</b>"
@@ -144,149 +72,6 @@ var/global/list/antag_names_to_ids = list()
/datum/antagonist/proc/get_extra_panel_options()
return
/datum/antagonist/proc/antags_are_dead()
for(var/datum/mind/antag in current_antagonists)
if(mob_path && !istype(antag.current,mob_path))
continue
if(antag.current.stat==2)
continue
return 0
return 1
/datum/antagonist/proc/get_antag_count()
return current_antagonists ? current_antagonists.len : 0
/datum/antagonist/proc/get_candidates(var/lower_count, var/upper_count, var/ghosts_only)
candidates = list()
var/main_type
if(ticker && ticker.mode)
if(ticker.mode.antag_tag && ticker.mode.antag_tag == id)
main_type = 1
else
return list()
var/cur_max = (main_type ? max_antags_round : max_antags)
if(ticker.mode.antag_scaling_coeff)
cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max)
if(get_antag_count() >= cur_max)
return list()
// Sanity.
if(lower_count)
lower_count = max(lower_count,1)
if(spawn_lower)
lower_count = max(lower_count,spawn_lower)
else
lower_count = 1
if(upper_count)
if(spawn_upper)
upper_count = max(min(spawn_upper, cur_max),1)
else
upper_count = 1
if(upper_count < lower_count)
upper_count = lower_count
candidates = list() // Clear.
candidates = ticker.mode.get_players_for_role(role_type, id)
// Prune restricted jobs and status.
for(var/datum/mind/player in candidates)
if((ghosts_only && !istype(player.current, /mob/dead)) || (player.assigned_role in restricted_jobs))
candidates -= player
if((!candidates.len) || candidates.len < lower_count)
return list()
return candidates
/datum/antagonist/proc/attempt_spawn(var/lower_count, var/upper_count, var/ghosts_only)
world << "Attempting to spawn."
// Get the raw list of potential players.
candidates = get_candidates(lower_count, upper_count, ghosts_only)
// Update our boundaries.
if(!candidates.len)
world << "No candidates."
return 0
//Grab candidates randomly until we have enough.
while(candidates.len)
var/datum/mind/player = pick(candidates)
current_antagonists |= player
// Update job and role.
player.special_role = role_text
if(flags & ANTAG_OVERRIDE_JOB)
player.assigned_role = "MODE"
candidates -= player
world << "Done."
return 1
/datum/antagonist/proc/apply(var/datum/mind/player)
// Get the mob.
if((flags & ANTAG_OVERRIDE_MOB) && (!player.current || (mob_path && !istype(player.current, mob_path))))
var/mob/holder = player.current
player.current = new mob_path(get_turf(player.current))
player.transfer_to(player.current)
if(holder) del(holder)
player.original = player.current
return player.current
/datum/antagonist/proc/create_objectives(var/datum/mind/player)
if(config.objectives_disabled)
return 0
if(global_objectives && global_objectives.len)
player.objectives |= global_objectives
return 1
/datum/antagonist/proc/equip(var/mob/living/carbon/human/player)
if(!istype(player))
return 0
// This could use work.
if(flags & ANTAG_CLEAR_EQUIPMENT)
for(var/obj/item/thing in player.contents)
del(thing)
return 1
/datum/antagonist/proc/unequip(var/mob/living/carbon/human/player)
if(!istype(player))
return 0
return 1
/datum/antagonist/proc/greet(var/datum/mind/player)
// Basic intro text.
player.current << "<span class='danger'><font size=3>You are a [role_text]!</font></span>"
if(leader_welcome_text && player.current == leader)
player.current << "<span class='notice'>[leader_welcome_text]</span>"
else
player.current << "<span class='notice'>[welcome_text]</span>"
show_objectives(player)
// Choose a name, if any.
if(flags & ANTAG_CHOOSE_NAME)
var/newname = sanitize(copytext(input(player.current, "You are a [role_text]. Would you like to change your name to something else?", "Name change") as null|text,1,MAX_NAME_LEN))
if (newname)
player.current.real_name = newname
player.current.name = player.current.real_name
player.name = player.current.name
// Clown clumsiness check, I guess downstream might use it.
if (player.current.mind)
if (player.current.mind.assigned_role == "Clown")
player.current << "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself."
player.current.mutations.Remove(CLUMSY)
return 1
/datum/antagonist/proc/get_starting_locations()
if(landmark_id)
starting_locations = list()
@@ -294,31 +79,22 @@ var/global/list/antag_names_to_ids = list()
if(L.name == landmark_id)
starting_locations |= get_turf(L)
/datum/antagonist/proc/create_global_objectives()
return !((global_objectives && global_objectives.len) || config.objectives_disabled)
/datum/antagonist/proc/place_all_mobs()
if(!starting_locations || !starting_locations.len || !current_antagonists || !current_antagonists.len)
return
for(var/datum/mind/player in current_antagonists)
player.current.loc = pick(starting_locations)
/datum/antagonist/proc/place_mob(var/mob/living/mob)
if(!starting_locations || !starting_locations.len)
return
mob.loc = pick(starting_locations)
/datum/antagonist/proc/finalize(var/datum/mind/target)
// This will fail if objectives have already been generated.
create_global_objectives()
if(flags & ANTAG_HAS_LEADER)
leader = current_antagonists[1]
if(leader && flags & ANTAG_HAS_NUKE && !spawned_nuke)
make_nuke(leader)
if(target)
apply(target)
equip(target.current)
create_objectives(target)
update_icons_added(target)
greet(target)
@@ -331,9 +107,6 @@ var/global/list/antag_names_to_ids = list()
update_icons_added(player)
greet(player)
if(flags & ANTAG_HAS_NUKE)
make_nuke(leader)
place_all_mobs()
spawn(1)
@@ -356,7 +129,7 @@ var/global/list/antag_names_to_ids = list()
text += print_player_full(P)
text += get_special_objective_text(P)
var/failed
if(!global_objectives && P.objectives && P.objectives.len)
if(!global_objectives.len && P.objectives && P.objectives.len)
var/num = 1
for(var/datum/objective/O in P.objectives)
text += print_objective(O, num)
@@ -367,6 +140,7 @@ var/global/list/antag_names_to_ids = list()
text += "<font color='red'>Fail.</font>"
feedback_add_details(feedback_tag,"[O.type]|FAIL")
failed = 1
num++
if(!config.objectives_disabled)
if(failed)
@@ -385,7 +159,7 @@ var/global/list/antag_names_to_ids = list()
world << text
/datum/antagonist/proc/print_objective(var/datum/objective/O, var/num, var/append_success)
var/text = "<BR/><B>Objective [num]:</B> [O.explanation_text] "
var/text = "<br><b>Objective [num]:</b> [O.explanation_text] "
if(append_success)
if(O.check_completion())
text += "<font color='green'><B>Success!</B></font>"
@@ -434,31 +208,6 @@ var/global/list/antag_names_to_ids = list()
return text
/datum/antagonist/proc/get_special_objective_text()
return ""
/datum/antagonist/proc/add_antagonist(var/datum/mind/player)
if(!istype(player))
return 0
if(player in current_antagonists)
return 0
if(!can_become_antag(player))
return 0
current_antagonists |= player
apply(player)
finalize(player)
return 1
/datum/antagonist/proc/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
if(player in current_antagonists)
player.current << "<span class='danger'><font size = 3>You are no longer a [role_text]!</font></span>"
current_antagonists -= player
player.special_role = null
update_icons_removed(player)
BITSET(player.current.hud_updateflag, SPECIALROLE_HUD)
return 1
return 0
/datum/antagonist/proc/update_all_icons()
if(!antag_indicator)
return
@@ -498,64 +247,4 @@ var/global/list/antag_names_to_ids = list()
if(I.icon_state == antag_indicator)
del(I)
/datum/antagonist/proc/can_become_antag(var/datum/mind/player)
if(player.current && jobban_isbanned(player.current, bantype))
return 0
if(player.assigned_role in protected_jobs)
return 0
if(config.protect_roles_from_antagonist && (player.assigned_role in restricted_jobs))
return 0
return 1
/datum/antagonist/proc/check_victory()
var/result
if(config.objectives_disabled)
return 1
if(!victory_text || !loss_text)
return 1
if(global_objectives && global_objectives.len)
for(var/datum/objective/O in global_objectives)
if(!O.completed && !O.check_completion())
result = 1 // Victory.
else
O.completed = 1 //Will this break anything?
if(result)
world << "<span class='danger'><font size = 3>[victory_text]</span>"
if(victory_feedback_tag) feedback_set_details("round_end_result","[victory_feedback_tag]")
else
world << "<span class='danger'><font size = 3>[loss_text]</span>"
if(loss_feedback_tag) feedback_set_details("round_end_result","[loss_feedback_tag]")
/datum/antagonist/proc/make_nuke(var/atom/paper_spawn_loc, var/datum/mind/code_owner)
// Decide on a code.
var/obj/effect/landmark/nuke_spawn = locate(nuke_spawn_loc ? nuke_spawn_loc : "landmark*Nuclear-Bomb")
var/code
if(nuke_spawn)
var/obj/machinery/nuclearbomb/nuke = new(get_turf(nuke_spawn))
code = "[rand(10000, 99999)]"
nuke.r_code = code
if(code)
if(!paper_spawn_loc)
paper_spawn_loc = get_turf(locate("landmark*Nuclear-Code"))
if(paper_spawn_loc)
// Create and pass on the bomb code paper.
var/obj/item/weapon/paper/P = new(paper_spawn_loc)
P.info = "The nuclear authorization code is: <b>[code]</b>"
P.name = "nuclear bomb code"
if(code_owner)
code_owner.store_memory("<B>Nuclear Bomb Code</B>: [code]", 0, 0)
code_owner.current << "The nuclear authorization code is: <B>[code]</B>"
else
world << "<spam class='danger'>Could not spawn nuclear bomb. Contact a developer.</span>"
return
return code
/datum/antagonist/proc/random_spawn()
return attempt_spawn((spawn_lower ? spawn_lower : 1),(spawn_upper ? spawn_upper : 1),(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB)))

View File

@@ -7,6 +7,9 @@
/datum/antagonist/proc/apply(var/datum/mind/player)
if(flags & ANTAG_HAS_LEADER && !leader)
leader = current_antagonists[1]
// Get the mob.
if((flags & ANTAG_OVERRIDE_MOB) && (!player.current || (mob_path && !istype(player.current, mob_path))))
var/mob/holder = player.current
@@ -48,13 +51,14 @@
// Choose a name, if any.
if(flags & ANTAG_CHOOSE_NAME)
var/newname = sanitize(copytext(input(player.current, "You are a [role_text]. Would you like to change your name to something else?", "Name change") as null|text,1,MAX_NAME_LEN))
if (newname)
player.current.real_name = newname
player.current.name = player.current.real_name
player.name = player.current.name
// Update any ID cards.
update_access(player.current)
spawn(5)
var/newname = sanitize(copytext(input(player.current, "You are a [role_text]. Would you like to change your name to something else?", "Name change") as null|text,1,MAX_NAME_LEN))
if (newname)
player.current.real_name = newname
player.current.name = player.current.real_name
player.name = player.current.name
// Update any ID cards.
update_access(player.current)
// Clown clumsiness check, I guess downstream might use it.
if (player.current.mind)
@@ -116,4 +120,5 @@
world << "<spam class='danger'>Could not spawn nuclear bomb. Contact a developer.</span>"
return
spawned_nuke = code
return code

View File

@@ -5,23 +5,19 @@
return ""
/datum/antagonist/proc/check_victory()
var/result
var/result = 1
if(config.objectives_disabled)
return 1
if(!victory_text || !loss_text)
return 1
if(global_objectives && global_objectives.len)
for(var/datum/objective/O in global_objectives)
if(!O.completed && !O.check_completion())
result = 1 // Victory.
result = 0
else
O.completed = 1 //Will this break anything?
if(result)
world << "<span class='danger'><font size = 3>[victory_text]</span>"
if(victory_feedback_tag) feedback_set_details("round_end_result","[victory_feedback_tag]")
else
world << "<span class='danger'><font size = 3>[loss_text]</span>"
if(loss_feedback_tag) feedback_set_details("round_end_result","[loss_feedback_tag]")
if(result && victory_text)
world << "<span class='danger'><font size = 3>[victory_text]</span>"
if(victory_feedback_tag) feedback_set_details("round_end_result","[victory_feedback_tag]")
else if(loss_text)
world << "<span class='danger'><font size = 3>[loss_text]</span>"
if(loss_feedback_tag) feedback_set_details("round_end_result","[loss_feedback_tag]")

View File

@@ -7,7 +7,6 @@
player.current << "<span class='danger'><i>You have been selected this round as an antagonist!</i></span>"
add_antagonist(player)
equip(player.current)
finalize(player)
if(move_to_spawn)
place_mob(player.current)
return
@@ -34,7 +33,6 @@
// Update our boundaries.
if(!candidates.len)
world << "Somehow there are no antagonist candidates."
return 0
//Grab candidates randomly until we have enough.
@@ -60,6 +58,7 @@
return 0
if(!can_become_antag(player))
return 0
current_antagonists |= player
apply(player)
finalize(player)
@@ -81,6 +80,6 @@
candidates = ticker.mode.get_players_for_role(role_type, id)
// Prune restricted jobs and status.
for(var/datum/mind/player in candidates)
if((ghosts_only && !istype(player.current, /mob/dead)) || (player.assigned_role in restricted_jobs))
if((ghosts_only && !istype(player.current, /mob/dead)) || player.special_role || (player.assigned_role in restricted_jobs))
candidates -= player
return candidates

View File

@@ -12,9 +12,7 @@ var/datum/antagonist/deathsquad/mercenary/commandos
commandos = src
/datum/antagonist/deathsquad/mercenary/equip(var/mob/living/carbon/human/player)
var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate(player)
R.set_frequency(SYND_FREQ) //Same frequency as the syndicate team in Nuke mode.
player.equip_to_slot_or_del(R, slot_l_ear)
player.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(player), slot_w_uniform)
player.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/silenced(player), slot_belt)
player.equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(player), slot_shoes)
@@ -25,4 +23,8 @@ var/datum/antagonist/deathsquad/mercenary/commandos
player.equip_to_slot_or_del(new /obj/item/ammo_magazine/c45(player), slot_in_backpack)
player.equip_to_slot_or_del(new /obj/item/weapon/rig/merc(player), slot_back)
player.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(player), slot_r_hand)
create_id("Commando", player)
var/obj/item/weapon/card/id/id = create_id("Commando", player)
id.access |= get_all_accesses()
id.icon_state = "centcom"
create_radio(SYND_FREQ, player)

View File

@@ -10,20 +10,9 @@ var/datum/antagonist/deathsquad/deathsquad
flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE
max_antags = 4
max_antags_round = 6
default_access = list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)
var/deployed = 0
/datum/antagonist/deathsquad/proc/create_id(var/assignment, var/mob/living/carbon/human/player)
var/obj/item/weapon/card/id/W = new(player)
W.name = "[player.real_name]'s ID Card"
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)
W.assignment = "[assignment]"
W.registered_name = player.real_name
player.equip_to_slot_or_del(W, slot_wear_id)
/datum/antagonist/deathsquad/New(var/no_reference)
..()
if(!no_reference)
@@ -38,9 +27,7 @@ var/datum/antagonist/deathsquad/deathsquad
player.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(player), slot_w_uniform)
else
player.equip_to_slot_or_del(new /obj/item/clothing/under/color/green(player), slot_w_uniform)
var/obj/item/device/radio/R = new /obj/item/device/radio/headset(player)
R.set_frequency(DTH_FREQ)
player.equip_to_slot_or_del(R, slot_l_ear)
player.equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(player), slot_shoes)
player.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(player), slot_gloves)
player.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(player), slot_glasses)
@@ -55,18 +42,25 @@ var/datum/antagonist/deathsquad/deathsquad
player.equip_to_slot_or_del(new /obj/item/weapon/rig/combat(player), slot_back)
player.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(player), slot_s_store)
player.implant_loyalty(player)
create_id("Asset Protection", player)
return
var/obj/item/weapon/card/id/id = create_id("Asset Protection", player)
id.access |= get_all_accesses()
id.icon_state = "centcom"
create_radio(DTH_FREQ, player)
/datum/antagonist/deathsquad/apply(var/datum/mind/player)
..()
//var/syndicate_commando_leader_rank = pick("Lieutenant", "Captain", "Major")
var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
var/syndicate_commando_rank
if(leader && player == leader)
syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
else
syndicate_commando_rank = pick("Lieutenant", "Captain", "Major")
var/syndicate_commando_name = pick(last_names)
var/datum/preferences/A = new()//Randomize appearance for the commando.
var/datum/preferences/A = new() //Randomize appearance for the commando.
A.randomize_appearance_for(player.current)
player.name = "[syndicate_commando_rank] [syndicate_commando_name]"
@@ -79,4 +73,11 @@ var/datum/antagonist/deathsquad/deathsquad
H.age = rand(25,45)
H.dna.ready_dna(H)
return
return
/datum/antagonist/deathsquad/finalize(var/datum/mind/target)
..()
if(!deployed)
deployed = 1

View File

@@ -11,7 +11,7 @@ var/datum/antagonist/ert/ert
max_antags = 5
max_antags_round = 5 // ERT mode?
flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB
flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE
/datum/antagonist/ert/New()
..()

View File

@@ -8,9 +8,10 @@ var/datum/antagonist/mercenary/mercs
role_text_plural = "Mercenaries"
landmark_id = "Syndicate-Spawn"
welcome_text = "To speak on the strike team's private channel use :t."
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_HAS_NUKE
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_HAS_NUKE | ANTAG_SET_APPEARANCE
max_antags = 4
max_antags_round = 6
id_type = /obj/item/weapon/card/id/syndicate
/datum/antagonist/mercenary/New()
..()
@@ -22,25 +23,23 @@ var/datum/antagonist/mercenary/mercs
global_objectives = list()
global_objectives |= new /datum/objective/nuclear
/datum/antagonist/mercenary/equip(var/mob/living/carbon/human/synd_mob)
/datum/antagonist/mercenary/equip(var/mob/living/carbon/human/player)
if(!..())
return 0
var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate(synd_mob)
R.set_frequency(SYND_FREQ)
R.freerange = 1
synd_mob.equip_to_slot_or_del(R, slot_l_ear)
synd_mob.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(synd_mob), slot_w_uniform)
synd_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(synd_mob), slot_shoes)
synd_mob.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(synd_mob), slot_gloves)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/card/id/syndicate(synd_mob), slot_wear_id)
if(synd_mob.backbag == 2) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(synd_mob), slot_back)
if(synd_mob.backbag == 3) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(synd_mob), slot_back)
if(synd_mob.backbag == 4) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(synd_mob), slot_back)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(synd_mob.back), slot_in_backpack)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(synd_mob), slot_in_backpack)
synd_mob.update_icons()
player.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(player), slot_w_uniform)
player.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(player), slot_shoes)
player.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(player), slot_gloves)
if(player.backbag == 2) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(player), slot_back)
if(player.backbag == 3) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(player), slot_back)
if(player.backbag == 4) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(player), slot_back)
player.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(player.back), slot_in_backpack)
player.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(player), slot_in_backpack)
player.update_icons()
create_id("Mercenary", player)
create_radio(SYND_FREQ, player)
return 1
/datum/antagonist/mercenary/place_all_mobs()

View File

@@ -8,7 +8,7 @@ var/datum/antagonist/ninja/ninjas
bantype = "ninja"
landmark_id = "ninjastart"
welcome_text = "You are an elite mercenary assassin of the Spider Clan. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor.</span>"
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
max_antags = 3
max_antags_round = 3

View File

@@ -7,109 +7,85 @@ var/datum/antagonist/raider/raiders
role_text_plural = "Raiders"
bantype = "raider"
landmark_id = "voxstart"
welcome_text = "Use :0 to speak Galcom, :H to talk on your encrypted channel, and don't forget to turn on your nitrogen internals!"
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE
spawn_lower = 4
spawn_upper = 6
welcome_text = "Use :H to talk on your encrypted channel."
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
max_antags = 6
max_antags_round = 10
id_type = /obj/item/weapon/card/id/syndicate
// Heist overrides check_victory() and doesn't need victory or loss strings/tags.
var/spawn_tick = 1
var/list/raider_uniforms = list(
/obj/item/clothing/under/soviet,
/obj/item/clothing/under/pirate,
/obj/item/clothing/under/redcoat,
/obj/item/clothing/under/serviceoveralls,
/obj/item/clothing/under/captain_fly
)
var/list/raider_shoes = list(
/obj/item/clothing/shoes/jackboots,
/obj/item/clothing/shoes/sandal,
/obj/item/clothing/shoes/laceup
)
var/list/raider_glasses = list(
/obj/item/clothing/glasses/thermal,
/obj/item/clothing/glasses/thermal/eyepatch,
/obj/item/clothing/glasses/thermal/monocle
)
var/list/raider_helmets = list(
/obj/item/clothing/head/bearpelt,
/obj/item/clothing/head/ushanka,
/obj/item/clothing/head/pirate,
/obj/item/clothing/head/bandana,
/obj/item/clothing/head/hgpiratecap,
/obj/item/clothing/head/flatcap
)
var/list/raider_suits = list(
/obj/item/clothing/suit/pirate,
/obj/item/clothing/suit/hgpirate,
/obj/item/clothing/suit/storage/toggle/bomber,
/obj/item/clothing/suit/storage/leather_jacket,
/obj/item/clothing/suit/storage/toggle/brown_jacket,
/obj/item/clothing/suit/storage/toggle/hoodie,
/obj/item/clothing/suit/storage/toggle/hoodie/black
)
var/list/raider_guns = list(
/obj/item/weapon/gun/energy/laser,
/obj/item/weapon/gun/energy/retro,
/obj/item/weapon/gun/energy/xray,
/obj/item/weapon/gun/energy/mindflayer,
/obj/item/weapon/gun/energy/toxgun,
/obj/item/weapon/gun/energy/stunrevolver,
/obj/item/weapon/gun/energy/crossbow/largecrossbow,
/obj/item/weapon/gun/projectile/automatic/mini_uzi,
/obj/item/weapon/gun/projectile/automatic/c20r,
/obj/item/weapon/gun/projectile/silenced,
/obj/item/weapon/gun/projectile/shotgun/pump,
/obj/item/weapon/gun/projectile/shotgun/pump/combat,
/obj/item/weapon/gun/projectile/colt,
/obj/item/weapon/gun/projectile/pistol
)
/datum/antagonist/raider/New()
..()
raiders = src
/datum/antagonist/raider/equip(var/mob/living/carbon/human/player)
if(!..())
return 0
player.age = rand(12,70)
player.set_species("Vox")
player.languages = list() // Removing language from chargen.
player.flavor_text = ""
player.add_language("Vox-pidgin")
player.add_language("Galactic Common")
player.add_language("Tradeband")
var/datum/language/voxlang = all_languages["Vox-pidgin"]
player.real_name = voxlang.get_random_name()
player.name = player.real_name
if(player.mind)
player.mind.name = player.name
player.h_style = "Short Vox Quills"
player.f_style = "Shaved"
for(var/datum/organ/external/limb in player.organs)
limb.status &= ~(ORGAN_DESTROYED | ORGAN_ROBOT)
player.regenerate_icons()
var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate(player)
R.set_frequency(SYND_FREQ)
player.equip_to_slot_or_del(R, slot_l_ear)
player.equip_to_slot_or_del(new /obj/item/clothing/under/vox/vox_robes(player), slot_w_uniform)
player.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/vox(player), slot_shoes) // REPLACE THESE WITH CODED VOX ALTERNATIVES.
player.equip_to_slot_or_del(new /obj/item/clothing/gloves/yellow/vox(player), slot_gloves) // AS ABOVE.
switch(spawn_tick)
if(1) // Vox raider!
player.equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/carapace(player), slot_wear_suit)
player.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/carapace(player), slot_head)
player.equip_to_slot_or_del(new /obj/item/weapon/melee/baton/loaded(player), slot_belt)
player.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(player), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
player.equip_to_slot_or_del(new /obj/item/device/chameleon(player), slot_l_store)
var/obj/item/weapon/gun/launcher/spikethrower/W = new(player)
player.equip_to_slot_or_del(W, slot_r_hand)
if(2) // Vox engineer!
player.equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/pressure(player), slot_wear_suit)
player.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/pressure(player), slot_head)
player.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(player), slot_belt)
player.equip_to_slot_or_del(new /obj/item/clothing/glasses/meson(player), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
player.equip_to_slot_or_del(new /obj/item/weapon/storage/box/emps(player), slot_r_hand)
player.equip_to_slot_or_del(new /obj/item/device/multitool(player), slot_l_hand)
if(3) // Vox saboteur!
player.equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/stealth(player), slot_wear_suit)
player.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/stealth(player), slot_head)
player.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(player), slot_belt)
player.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(player), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
player.equip_to_slot_or_del(new /obj/item/weapon/card/emag(player), slot_l_store)
player.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/dartgun/vox/raider(player), slot_r_hand)
player.equip_to_slot_or_del(new /obj/item/device/multitool(player), slot_l_hand)
if(4) // Vox medic!
player.equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/medic(player), slot_wear_suit)
player.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/medic(player), slot_head)
player.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(player), slot_belt) // Who needs actual surgical tools?
player.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/health(player), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
player.equip_to_slot_or_del(new /obj/item/weapon/circular_saw(player), slot_l_store)
player.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/dartgun/vox/medical, slot_r_hand)
player.equip_to_slot_or_del(new /obj/item/clothing/mask/breath(player), slot_wear_mask)
player.equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(player), slot_back)
player.equip_to_slot_or_del(new /obj/item/device/flashlight(player), slot_r_store)
var/obj/item/weapon/card/id/syndicate/C = new(player)
C.name = "[player.real_name]'s Legitimate Human ID Card"
C.icon_state = "id"
C.access = list(access_syndicate)
C.assignment = "Trader"
C.registered_name = player.real_name
C.registered_user = player
var/obj/item/weapon/storage/wallet/W = new(player)
W.handle_item_insertion(C)
spawn_money(rand(50,150)*10,W)
player.equip_to_slot_or_del(W, slot_wear_id)
spawn_tick++
if (spawn_tick > 4) spawn_tick = 1
/datum/antagonist/raider/update_access(var/mob/living/player)
for(var/obj/item/weapon/storage/wallet/W in player.contents)
for(var/obj/item/weapon/card/id/id in W.contents)
id.name = "[player.real_name]'s Passport"
id.registered_name = player.real_name
W.name = "[initial(W.name)] ([id.name])"
/datum/antagonist/raider/create_global_objectives()
if(global_objectives.len)
return
var/i = 1
var/max_objectives = pick(2,2,2,2,3,3,3,4)
global_objectives = list()
@@ -130,9 +106,7 @@ var/datum/antagonist/raider/raiders
i++
//-All- vox raids have these two objectives. Failing them loses the game.
global_objectives |= new /datum/objective/heist/inviolate_crew
global_objectives |= new /datum/objective/heist/inviolate_death
global_objectives |= new /datum/objective/heist/preserve_crew
/datum/antagonist/raider/check_victory()
// Totally overrides the base proc.
@@ -151,10 +125,10 @@ var/datum/antagonist/raider/raiders
//Set result by objectives.
if(success == global_objectives.len)
win_type = "Major"
win_group = "Vox"
win_group = "Raider"
else if(success > 2)
win_type = "Minor"
win_group = "Vox"
win_group = "Raider"
else
win_type = "Minor"
win_group = "Crew"
@@ -162,19 +136,19 @@ var/datum/antagonist/raider/raiders
if(antags_are_dead())
win_type = "Major"
win_group = "Crew"
win_msg += "<B>The Vox Raiders have been wiped out!</B>"
win_msg += "<B>The Raiders have been wiped out!</B>"
else if(is_raider_crew_safe())
if(win_group == "Crew" && win_type == "Minor")
win_type = "Major"
win_group = "Crew"
win_msg += "<B>The Vox Raiders have left someone behind!</B>"
win_msg += "<B>The Raiders have left someone behind!</B>"
else
if(win_group == "Vox")
if(win_group == "Raider")
if(win_type == "Minor")
win_type = "Major"
win_msg += "<B>The Vox Raiders escaped the station!</B>"
win_msg += "<B>The Raiders escaped the station!</B>"
else
win_msg += "<B>The Vox Raiders were repelled!</B>"
win_msg += "<B>The Raiders were repelled!</B>"
world << "<span class='danger'><font size = 3>[win_type] [win_group] victory!</font>"
world << "[win_msg]"
@@ -182,10 +156,61 @@ var/datum/antagonist/raider/raiders
/datum/antagonist/raider/proc/is_raider_crew_safe()
if(cortical_stacks.len == 0)
if(!current_antagonists || current_antagonists.len == 0)
return 0
for(var/datum/organ/internal/stack/vox/stack in cortical_stacks)
if(stack.organ_holder && get_area(stack.organ_holder) != locate(/area/shuttle/vox/station))
for(var/datum/mind/player in current_antagonists)
if(!player.current || get_area(player.current) != locate(/area/shuttle/skipjack/station))
return 0
return 1
return 1
/datum/antagonist/raider/equip(var/mob/living/carbon/human/player)
if(!..())
return 0
if(player.species && player.species.name == "Vox")
equip_vox(player)
else
var/new_shoes = pick(raider_shoes)
var/new_uniform = pick(raider_uniforms)
var/new_glasses = pick(raider_glasses)
var/new_helmet = pick(raider_helmets)
var/new_suit = pick(raider_suits)
var/new_gun = pick(raider_guns)
player.equip_to_slot_or_del(new new_shoes(player),slot_shoes)
player.equip_to_slot_or_del(new new_uniform(player),slot_w_uniform)
player.equip_to_slot_or_del(new new_glasses(player),slot_glasses)
player.equip_to_slot_or_del(new new_helmet(player),slot_head)
player.equip_to_slot_or_del(new new_suit(player),slot_wear_suit)
player.equip_to_slot_or_del(new new_gun(player),slot_belt)
var/obj/item/weapon/card/id/id = create_id("Visitor", player)
id.name = "[player.real_name]'s Passport"
id.assignment = "Visitor"
var/obj/item/weapon/storage/wallet/W = new(player)
W.handle_item_insertion(id)
player.equip_to_slot_or_del(W, slot_wear_id)
spawn_money(rand(50,150)*10,W)
create_radio(SYND_FREQ, player)
return 1
/datum/antagonist/raider/proc/equip_vox(var/mob/living/carbon/human/player)
var/uniform_type = pick(list(/obj/item/clothing/under/vox/vox_robes,/obj/item/clothing/under/vox/vox_casual))
player.equip_to_slot_or_del(new uniform_type(player), slot_w_uniform)
player.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/vox(player), slot_shoes) // REPLACE THESE WITH CODED VOX ALTERNATIVES.
player.equip_to_slot_or_del(new /obj/item/clothing/gloves/yellow/vox(player), slot_gloves) // AS ABOVE.
player.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat/vox(player), slot_wear_mask)
player.equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(player), slot_back)
player.equip_to_slot_or_del(new /obj/item/device/flashlight(player), slot_r_store)
player.internal = locate(/obj/item/weapon/tank) in player.contents
if(istype(player.internal,/obj/item/weapon/tank) && player.internals)
player.internals.icon_state = "internal1"
return 1

View File

@@ -8,9 +8,8 @@ var/datum/antagonist/wizard/wizards
bantype = "wizard"
landmark_id = "wizard"
welcome_text = "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.<br>In your pockets you will find a teleport scroll. Use it as needed."
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE
spawn_lower = 1
spawn_upper = 1
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
max_antags = 1
/datum/antagonist/wizard/New()
..()

View File

@@ -23,7 +23,7 @@ var/datum/antagonist/rogue_ai/malf
hacked_apcs |= apc
/datum/antagonist/rogue_ai/proc/update_takeover_time()
hack_time -= ((hacked_apcs.len/6)*last_tick_duration)
hack_time -= ((hacked_apcs.len/6)*tickerProcess.getLastTickerTimeDuration())
/datum/antagonist/rogue_ai/tick()
if(revealed && hacked_apcs.len >= 3)
@@ -54,7 +54,7 @@ var/datum/antagonist/rogue_ai/malf
player.verbs += /mob/living/silicon/ai/proc/takeover
player.verbs += /mob/living/silicon/ai/proc/self_destruct
player.laws = new /datum/ai_laws/malfunction
player.laws = new /datum/ai_laws/nanotrasen/malfunction
player.malf_picker = new /datum/AI_Module/module_picker
/datum/antagonist/rogue_ai/greet(var/datum/mind/player)

View File

@@ -20,10 +20,9 @@
break
additional_antag_types |= antag_id
i++
..()
/datum/game_mode/calamity/check_victory()
world << "<font size = 3><b>This terrible, terrible day has finally ended!</b></font>"
#undef ANTAG_TYPE_RATIO
#undef ANTAG_TYPE_RATIO

View File

@@ -249,14 +249,7 @@ var/global/list/additional_antag_types = list()
if(playerC < required_players)
return 0
// If we can, -try- to spawn the other voted antagonist types. It doesn't really matter if we can't.
if(!do_not_spawn)
if(antag_templates && antag_templates.len)
var/datum/antagonist/main_antags = antag_templates[1]
var/list/candidates = main_antags.get_candidates(required_enemies)
if(candidates.len > required_enemies)
return 1
else
if(!(antag_templates && antag_templates.len))
return 1
// Attempt to mark folks down as ready to go. Don't finalize until post setup.

View File

@@ -1,5 +1,5 @@
/*
HEIST ROUNDTYPE
VOX HEIST ROUNDTYPE
*/
var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' objective. Clumsy, rewrite sometime.
@@ -11,26 +11,21 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
required_players = 15
required_players_secret = 25
required_enemies = 4
votable = 0
round_description = "An unidentified bluespace signature has slipped past the Icarus and is approaching the station!"
end_on_antag_death = 1
/datum/game_mode/heist/check_finished()
if(!..())
var/datum/shuttle/multi_shuttle/skipjack = shuttle_controller.shuttles["Vox Skipjack"]
var/datum/shuttle/multi_shuttle/skipjack = shuttle_controller.shuttles["Skipjack"]
if (skipjack && skipjack.returned_home)
return 1
return 0
/datum/game_mode/heist/cleanup()
//the skipjack and everything in it have left and aren't coming back, so get rid of them.
var/area/skipjack = locate(/area/shuttle/skipjack/station)
for (var/mob/living/M in skipjack.contents)
//maybe send the player a message that they've gone home/been kidnapped? Someone responsible for vox lore should write that.
del(M)
for (var/obj/O in skipjack.contents)
del(O) //no hiding in lockers or anything

View File

@@ -11,11 +11,9 @@
auto_recall_shuttle = 1
antag_tag = MODE_MALFUNCTION
/datum/game_mode/malfunction/process()
malf.tick()
/datum/game_mode/malfunction/check_finished()
if (malf.station_captured && !malf.can_nuke)
return 1

View File

@@ -713,7 +713,7 @@ datum/objective/heist/kidnap
target = pick(possible_targets)
if(target && target.current)
explanation_text = "The Shoal has a need for [target.current.real_name], the [target.assigned_role]. Take them alive."
explanation_text = "We can get a good price for [target.current.real_name], the [target.assigned_role]. Take them alive."
else
explanation_text = "Free Objective"
return target
@@ -770,7 +770,7 @@ datum/objective/heist/loot
target_amount = 1
loot = "an ion gun"
explanation_text = "We are lacking in hardware. Steal [loot]."
explanation_text = "It's a buyer's market out here. Steal [loot] for resale."
check_completion()
@@ -850,25 +850,14 @@ datum/objective/heist/salvage
return 0
/datum/objective/heist/inviolate_crew
/datum/objective/heist/preserve_crew
explanation_text = "Do not leave anyone behind, alive or dead."
check_completion()
if(raiders && raiders.is_raider_crew_safe()) return 1
return 0
#define MAX_RAIDER_KILLS 10 //Number of kills during the round before the Inviolate is broken.
//Would be nice to use raider-specific kills but is currently not feasible.
var/global/raider_kills = 0 //Used to check the Inviolate.
datum/objective/heist/inviolate_death
explanation_text = "Minimise deaths and loss of resources."
check_completion()
if(raider_kills > MAX_RAIDER_KILLS) return 0
return 1
//Borer objective(s).
/datum/objective/borer_survive
explanation_text = "Survive in a host until the end of the round."

View File

@@ -79,7 +79,7 @@
if(choice && choice == "Yes")
var/mob/living/carbon/human/vox/vox = new(get_turf(src),"Vox")
vox.gender = user.gender
vox.equip_vox_raider()
raiders.equip(vox)
if(user.mind)
user.mind.transfer_to(vox)
spawn(1)
@@ -90,5 +90,6 @@
newname = L.get_random_name()
vox.real_name = newname
vox.name = vox.real_name
raiders.update_access(vox)
del(user)
..()
..()

View File

@@ -65,8 +65,6 @@
if(ticker && ticker.mode)
sql_report_death(src)
ticker.mode.check_win()
if(istype(ticker.mode,/datum/game_mode/heist))
raider_kills++ //Bad raider. Shouldn't be killing people.
return ..(gibbed,species.death_message)

View File

@@ -809,7 +809,7 @@ var/list/be_special_flags = list(
#define ANTAG_HAS_NUKE 128 // Will spawn a nuke at supplied location.
#define ANTAG_RANDSPAWN 256 // Potentially randomly spawns due to events.
#define ANTAG_VOTABLE 512 // Can be voted as an additional antagonist before roundstart.
#define ANTAG_SET_APPEARANCE 1024 // Causes antagonists to use an appearance modifier on spawn.
// Mode/antag template macros.
#define MODE_BORER "borer"
#define MODE_XENOMORPH "xeno"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff