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

@@ -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"