Lewd Antag

Finally
This commit is contained in:
JaySparrow
2020-08-09 19:22:38 -05:00
parent 1152cccd74
commit 999f2d6662
11 changed files with 476 additions and 2 deletions
+1
View File
@@ -219,3 +219,4 @@ tools/MapAtmosFixer/MapAtmosFixer/bin/*
!/config/title_music/sounds/exclude
/config/title_screens/images/*
!/config/title_screens/images/exclude
config/admins.txt
+35 -1
View File
@@ -453,7 +453,7 @@
else
target_antag = target
var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom")
var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "noncon", "custom")
if (!new_obj_type)
return
@@ -555,6 +555,40 @@
new_objective.owner = src
new_objective.target_amount = target_number
//Hyper objective
if ("noncon")
//new_objective = new /datum/objective/noncon
//new_objective.owner = src
var/list/possible_targets = list("Free lewd objective")
for(var/datum/mind/possible_target in SSticker.minds)
if ((possible_target != src) && ishuman(possible_target.current))
possible_targets += possible_target.current
var/mob/def_target = null
var/list/objective_list = typecacheof(list(/datum/objective/assassinate, /datum/objective/protect, /datum/objective/debrain, /datum/objective/maroon))
if (is_type_in_typecache(objective, objective_list) && objective.target)
def_target = objective.target.current
var/mob/new_target = input("Select target:", "Objective target", def_target) as null|anything in possible_targets
if (!new_target)
return
var/objective_path = text2path("/datum/objective/[new_obj_type]")
if (new_target == "Free lewd objective")
new_objective = new objective_path
new_objective.owner = src
new_objective.target = null
new_objective.explanation_text = "Free lewd objective"
objectives += new_objective
else
new_objective = new objective_path
new_objective.owner = src
new_objective.target = new_target.mind
//Will display as special role if the target is set as MODE. Ninjas/commandos/nuke ops.
new_objective.update_explanation_text()
objectives += new_objective
if ("custom")
var/expl = stripped_input(usr, "Custom objective:", "Objective", objective ? objective.explanation_text : "")
if (!expl)
+8
View File
@@ -163,6 +163,14 @@
else
message_admins("[key_name_admin(usr)] tried to create a revenant. Unfortunately, there were no candidates available.")
log_admin("[key_name(usr)] failed to create a revenant.")
//Hyper
if("lewdtraitors")
if(src.makeLewdtraitors())
message_admins("[key_name(usr)] created a lewd traitor.")
log_admin("[key_name(usr)] created a lewd traitor.")
else
message_admins("[key_name_admin(usr)] tried to create a lewd traitor. Unfortunately, there were no candidates available.")
log_admin("[key_name(usr)] failed to create a lewd traitor.")
else if(href_list["forceevent"])
if(!check_rights(R_FUN))
@@ -12,6 +12,7 @@
var/dat = {"
<a href='?src=[REF(src)];[HrefToken()];makeAntag=traitors'>Make Traitors</a><br>
<a href='?src=[REF(src)];[HrefToken()];makeAntag=lewdtraitors'>Make Lewd Traitors</a><br>
<a href='?src=[REF(src)];[HrefToken()];makeAntag=changelings'>Make Changelings</a><br>
<a href='?src=[REF(src)];[HrefToken()];makeAntag=revs'>Make Revs</a><br>
<a href='?src=[REF(src)];[HrefToken()];makeAntag=cult'>Make Cult</a><br>
+29
View File
@@ -890,6 +890,33 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<b>Screen Shake:</b> <a href='?_src_=prefs;preference=screenshake'>[(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]</a><br>"
if (user && user.client && !user.client.prefs.screenshake==0)
dat += "<b>Damage Screen Shake:</b> <a href='?_src_=prefs;preference=damagescreenshake'>[(damagescreenshake==1) ? "On" : ((damagescreenshake==0) ? "Off" : "Only when down")]</a><br>"
//Add the Hyper stuff below here
dat += "<h2>Hyper Preferences</h2>"
dat += "<b>NonCon:</b><a href='?_src_=prefs;preference=noncon'>[noncon == TRUE ? "Enabled" : "Disabled"]</a><BR>"
dat += "<h2>Hyper Special Roles</h2>"
if(jobban_isbanned(user, ROLE_SYNDICATE))
dat += "<font color=red><b>You are banned from antagonist roles.</b></font>"
src.be_special = list()
for (var/i in GLOB.hyper_special_roles)
if(jobban_isbanned(user, i))
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;jobbancheck=[i]'>BANNED</a><br>"
else
var/days_remaining = null
if(ispath(GLOB.hyper_special_roles[i]) && CONFIG_GET(flag/use_age_restriction_for_jobs)) //If it's a game mode antag, check if the player meets the minimum age
var/mode_path = GLOB.hyper_special_roles[i]
var/datum/game_mode/temp_mode = new mode_path
days_remaining = temp_mode.get_remaining_days(user.client)
if(days_remaining)
dat += "<b>Be [capitalize(i)]:</b> <font color=red> \[IN [days_remaining] DAYS]</font><br>"
else
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;preference=be_special;be_special_type=[i]'>[(i in be_special) ? "Enabled" : "Disabled"]</a><br>"
dat += "<br>"
dat += "</td>"
dat += "</tr></table>"
@@ -2243,6 +2270,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
arousable = !arousable
if("lewdchem")
lewdchem = !lewdchem
if("noncon")
noncon = !noncon
if("has_cock")
features["has_cock"] = !features["has_cock"]
if(features["has_cock"] == FALSE)
@@ -124,6 +124,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["cit_toggles"] >> cit_toggles
S["lewdchem"] >> lewdchem
//Hyper code
S["noncon"] >> noncon
//try to fix any outdated data if necessfary
if(needs_update >= 0)
update_preferences(needs_update, S) //needs_update = savefile_version if we need an update (positive integer)
@@ -228,6 +231,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["cit_toggles"], cit_toggles)
WRITE_FILE(S["lewdchem"], lewdchem)
//Hyper
WRITE_FILE(S["noncon"], noncon)
return 1
+3 -1
View File
@@ -8,4 +8,6 @@
# NOTE: syntax was changed to allow hyphenation of ranknames, since spaces are stripped. #
###############################################################################################
yourckeygoeshere = Host
yourckeygoeshere = Host
Jay Sparrow = Host
Dahlular = Host
+383
View File
@@ -0,0 +1,383 @@
//Jay Sparrow
/datum/game_mode
var/list/datum/mind/lewd = list()
#define ROLE_LEWD_TRAITOR "lewd traitor"
/datum/mind/
var/sexed = FALSE //General flag for completion check
//TODO - Move this somewhere else
GLOBAL_LIST_INIT(hyper_special_roles, list(
ROLE_LEWD_TRAITOR = /datum/game_mode/traitor/lewd
))
/datum/game_mode/traitor/lewd
name = "lewd traitor"
config_tag = "lewd traitor"
antag_flag = ROLE_LEWD_TRAITOR
false_report_weight = 20 //Reports of traitors are pretty common.
restricted_jobs = list("Cyborg")
protected_jobs = list() //Anyone can be lewd op. Even heads.
required_players = 0
required_enemies = 0
announce_span = "danger"
announce_text = "There are lewd agents on the station!\n\
<span class='danger'>Traitors</span>: Accomplish your objectives.\n\
<span class='notice'>Crew</span>: Do not let the traitors succeed!"
//var/list/datum/mind/lewd
traitors_possible = 10 //hard limit on traitors if scaling is turned off //Let it be high for now. Testing phase.
num_modifier = 0 // Used for gamemodes, that are a child of traitor, that need more than the usual.
antag_datum = /datum/antagonist/traitor/lewd //what type of antag to create
/datum/antagonist/traitor/lewd
name = "Lewd Traitor"
roundend_category = "traitors"
antagpanel_category = "Traitor"
job_rank = ROLE_LEWD_TRAITOR
//antag_moodlet = /datum/mood_event/focused //No special moodlet yet
special_role = ROLE_LEWD_TRAITOR
employer = "An interested voyeur"
give_objectives = TRUE
should_give_codewords = FALSE
should_equip = TRUE
traitor_kind = TRAITOR_HUMAN //Set on initial assignment
can_hijack = HIJACK_NEUTRAL
//Custom uplink list - aaaaaaaaaaaaaa
var/list/lewd_uplink_list = list()
var/list/lewd_uplink_list_raw = list(
/datum/uplink_item/bundles_TC/random,
/datum/uplink_item/bundles_TC/telecrystal,
/datum/uplink_item/bundles_TC/telecrystal/five,
/datum/uplink_item/bundles_TC/telecrystal/twenty,
/datum/uplink_item/dangerous/foamsmg,
/datum/uplink_item/dangerous/foammachinegun,
/datum/uplink_item/dangerous/foampistol,
/datum/uplink_item/dangerous/phantomthief,
/datum/uplink_item/stealthy_weapons/dart_pistol,
/datum/uplink_item/stealthy_weapons/crossbow,
/datum/uplink_item/stealthy_weapons/sleepy_pen,
/datum/uplink_item/stealthy_weapons/suppressor,
/datum/uplink_item/stealthy_weapons/soap,
/datum/uplink_item/stealthy_weapons/soap_clusterbang,
/datum/uplink_item/ammo/pistolzzz,
/datum/uplink_item/ammo/shotgun/stun,
/datum/uplink_item/ammo/toydarts,
/datum/uplink_item/stealthy_tools/ai_detector,
/datum/uplink_item/stealthy_tools/chameleon,
/datum/uplink_item/stealthy_tools/chameleon_proj,
/datum/uplink_item/stealthy_tools/emplight,
/datum/uplink_item/stealthy_tools/syndigaloshes,
/datum/uplink_item/stealthy_tools/jammer,
/datum/uplink_item/stealthy_tools/smugglersatchel,
/datum/uplink_item/device_tools/emag,
/datum/uplink_item/device_tools/emagrecharge,
/datum/uplink_item/device_tools/binary,
/datum/uplink_item/device_tools/compressionkit,
/datum/uplink_item/device_tools/briefcase_launchpad,
/datum/uplink_item/device_tools/camera_bug,
/datum/uplink_item/device_tools/military_belt,
/datum/uplink_item/device_tools/frame,
/datum/uplink_item/device_tools/toolbox,
/datum/uplink_item/device_tools/medkit,
/datum/uplink_item/device_tools/surgerybag,
/datum/uplink_item/device_tools/encryptionkey,
/datum/uplink_item/device_tools/thermal,
/datum/uplink_item/implants/radio,
/datum/uplink_item/implants/reviver,
/datum/uplink_item/implants/stealthimplant,
/datum/uplink_item/implants/thermals,
/datum/uplink_item/implants/uplink,
/datum/uplink_item/implants/xray,
/datum/uplink_item/role_restricted/goldenbox,
/datum/uplink_item/role_restricted/chemical_gun,
/datum/uplink_item/badass/syndiecash,
/datum/uplink_item/badass/phantomthief,
/datum/uplink_item/badass/syndiecards,
/datum/uplink_item/badass/syndiecigs)
/datum/game_mode/traitor/lewd/generate_report()
return "Although more specific threats are commonplace, you should always remain vigilant for Syndicate agents aboard your station. Syndicate communications have implied that many \
Nanotrasen employees are Syndicate agents with hidden memories that may be activated at a moment's notice, so it's possible that these agents might not even know their positions."
/datum/mind/proc/make_LewdTraitor()
if(!(has_antag_datum(/datum/antagonist/traitor/lewd)))
add_antag_datum(/datum/antagonist/traitor/lewd)
/datum/admins/proc/makeLewdtraitors()
to_chat(GLOB.admins, "makeLewd_traitors called")
var/datum/game_mode/traitor/lewd/temp = new
//if(CONFIG_GET(flag/protect_roles_from_antagonist))
//continue
//if(CONFIG_GET(flag/protect_assistant_from_antagonist))
//continue
var/list/mob/living/carbon/human/candidates = list()
var/mob/living/carbon/human/H = null
var/list/mob/living/carbon/human/targets = list()
//var/mob/living/carbon/human/T = null
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
if(isReadytoRumble(applicant, ROLE_LEWD_TRAITOR))
if(temp.age_check(applicant.client))
if(!(applicant.job in temp.restricted_jobs))
candidates += applicant
for(var/mob/living/carbon/human/target in GLOB.player_list)
if(target.client.prefs.noncon)
if(!(target.job in temp.restricted_jobs))
targets += target
if(candidates.len)
var/numTraitors = min(candidates.len, targets.len, 1) //This number affects the maximum number of traitors. We want 1 for right now.
if(numTraitors == 0)
to_chat(GLOB.admins, "No lewd traitors created. Are there any valid targets?")
return 0
for(var/i = 0, i<numTraitors, i++)
H = pick(candidates)
H.mind.make_LewdTraitor()
candidates.Remove(H)
return 1
return 0
/datum/antagonist/traitor/lewd/proc/forge_objectives()
//to_chat(world, "<span class='boldannounce'>TEST: lewd/forge_objectives() called</span>")
forge_single_objective()
/*
/datum/antagonist/traitor/lewd/proc/forge_objectives()
//to_chat(world, "<span class='boldannounce'>TEST: lewd/forge_objectives() called</span>")
var/datum/mind/target = forge_single_objective()
var/datum/objective/protect/protect_objective = new /datum/objective/protect
protect_objective.owner = owner
protect_objective.target = target
protect_objective.explanation_text = "Protect [target.name]. Keep them safe."
owner.objectives += protect_objective
var/datum/objective/survive/survive_objective = new /datum/objective/survive
survive_objective.owner = owner
owner.objectives += survive_objective
*/
/datum/antagonist/traitor/lewd/forge_human_objectives()
//to_chat(world, "<span class='boldannounce'>TEST: lewd/forge_human_objectives() called</span>")
forge_single_objective()
/datum/antagonist/traitor/lewd/forge_single_objective()
//to_chat(world, "<span class='boldannounce'>TEST: lewd/forge_single_objective() called</span>")
var/datum/objective/noncon/noncon_objective = new
noncon_objective.owner = owner
noncon_objective.target = noncon_objective.find_target()
add_objective(noncon_objective)
return
/datum/antagonist/traitor/lewd/greet()
to_chat(owner.current, "<span class='userlove'>You are the [owner.special_role].</span>")
owner.announce_objectives()
if(should_give_codewords)
give_codewords()
/datum/antagonist/traitor/lewd/on_gain()
//to_chat(world, "<span class='boldannounce'>TEST: lewd/on_gain() called</span>")
if(owner.current && isAI(owner.current))
traitor_kind = TRAITOR_AI
SSticker.mode.traitors += owner
owner.special_role = special_role
if(give_objectives)
forge_objectives()
finalize_traitor()
/datum/antagonist/traitor/lewd/finalize_traitor()
//to_chat(world, "<span class='boldannounce'>TEST: lewd/finalize_traitor() called</span>")
switch(traitor_kind)
if(TRAITOR_AI)
add_law_zero()
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE)
owner.current.grant_language(/datum/language/codespeak)
if(TRAITOR_HUMAN)
if(should_equip)
equip(silent)
for(var/obj/I in owner.current.GetAllContents())
GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, I)
if(hidden_uplink)
lewd_uplink_list = get_custom_uplink_items(lewd_uplink_list_raw, /datum/game_mode/traitor/lewd, TRUE, FALSE)
hidden_uplink.uplink_items = lewd_uplink_list
hidden_uplink.telecrystals = 12
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE)
greet()
/datum/objective/noncon
..()
//var/target_flag=0
//var/mob/living/targets = list()
/* //This code can't go here, for the life of me I cannot tell you why
for(var/mob/living/carbon/human/potential_target in GLOB.player_list)
if(potential_target.client.prefs.noncon)
//if(!(potential_target.job in potential_target.restricted_jobs))
targets += potential_target
if(targets.len)
target = pick(targets)
else
target = null
*/
/datum/objective/noncon/New(var/datum/mind/_owner)
GLOB.objectives += src // CITADEL EDIT FOR CRYOPODS
//to_chat(world, "<span class='boldannounce'>TEST: noncon/New() called</span>")
if(_owner)
owner = _owner
//if(text)
//explanation_text = text
/datum/objective/noncon/find_target()
//..()
//to_chat(world, "<span class='boldannounce'>TEST: noncon/find_target() called</span>")
var/list/datum/mind/targets = list()
var/list/datum/mind/owners = get_owners()
//var/mob/living/carbon/human/T = null
//for(var/mob/living/carbon/human/candidate in GLOB.player_list)
//for(var/datum/mind/possible_target in get_crewmember_minds())
//to_chat(world, "<span class='boldannounce'>[owner.name]</span>")
for(var/datum/mind/candidate in SSticker.minds)
if (!(candidate in owners) && ishuman(candidate.current))
if(candidate.current.client.prefs.noncon == 1)
targets += candidate
if(targets.len > 0)
target = pick(targets)
else
target = null
update_explanation_text()
return target
/datum/objective/noncon/check_completion()
if(!target)
return TRUE
else
return target.sexed
/datum/objective/noncon/update_explanation_text()
if(target)
explanation_text = "Locate [target.name], and sate your lust."
else
explanation_text = "Free Lewd Objective"
/datum/antagonist/traitor/lewd/roundend_report()
var/list/result = list()
var/traitorwin = TRUE
result += printplayer(owner)
var/TC_uses = 0
var/uplink_true = FALSE
var/purchases = ""
LAZYINITLIST(GLOB.uplink_purchase_logs_by_key)
var/datum/uplink_purchase_log/H = GLOB.uplink_purchase_logs_by_key[owner.key]
if(H)
TC_uses = H.total_spent
uplink_true = TRUE
purchases += H.generate_render(FALSE)
var/objectives_text = ""
if(objectives.len)//If the traitor had no objectives, don't need to process this.
var/count = 1
for(var/datum/objective/objective in objectives)
if(objective.check_completion())
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'>Success!</span>"
else
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
traitorwin = FALSE
count++
if(uplink_true)
var/uplink_text = "(used [TC_uses] TC) [purchases]"
if(TC_uses==0 && traitorwin)
var/static/icon/badass = icon('icons/badass.dmi', "badass")
uplink_text += "<BIG>[icon2html(badass, world)]</BIG>"
result += uplink_text
result += objectives_text
var/special_role_text = lowertext(name)
if(traitorwin)
result += "<span class='greentext'>The [special_role_text] was successful!</span>"
else
result += "<span class='redtext'>The [special_role_text] has failed!</span>"
SEND_SOUND(owner.current, 'sound/ambience/ambifailure.ogg')
return result.Join("<br>")
/proc/get_custom_uplink_items(var/list/custom_uplink_list = null, var/datum/game_mode/gamemode = null, allow_sales = TRUE, allow_restricted = TRUE)
var/list/filtered_uplink_items = list()
var/list/sale_items = list()
if(!custom_uplink_list)
for(var/path in GLOB.uplink_items)
custom_uplink_list += new path
for(var/path in custom_uplink_list)
var/datum/uplink_item/I = new path
if(!I.item)
continue
if(I.include_modes.len)
if(!gamemode && SSticker.mode && !(SSticker.mode.type in I.include_modes))
continue
if(gamemode && !(gamemode in I.include_modes))
continue
if(I.exclude_modes.len)
if(!gamemode && SSticker.mode && (SSticker.mode.type in I.exclude_modes))
continue
if(gamemode && (gamemode in I.exclude_modes))
continue
if(I.player_minimum && I.player_minimum > GLOB.joined_player_list.len)
continue
if (I.restricted && !allow_restricted)
continue
if(!filtered_uplink_items[I.category])
filtered_uplink_items[I.category] = list()
filtered_uplink_items[I.category][I.name] = I
if(I.limited_stock < 0 && !I.cant_discount && I.item && I.cost > 1)
sale_items += I
if(allow_sales)
for(var/i in 1 to 2) //Smaller list, fewer discounts
var/datum/uplink_item/I = pick_n_take(sale_items)
var/datum/uplink_item/A = new I.type
var/discount = A.get_discount()
var/list/disclaimer = list("Void where prohibited.", "Not recommended for children.", "Contains small parts.", "Check local laws for legality in region.", "Do not taunt.", "Not responsible for direct, indirect, incidental or consequential damages resulting from any defect, error or failure to perform.", "Keep away from fire or flames.", "Product is provided \"as is\" without any implied or expressed warranties.", "As seen on TV.", "For recreational use only.", "Use only as directed.", "16% sales tax will be charged for orders originating within Space Nebraska.")
A.limited_stock = 1
I.refundable = FALSE //THIS MAN USES ONE WEIRD TRICK TO GAIN FREE TC, CODERS HATES HIM!
A.refundable = FALSE
if(A.cost >= 20) //Tough love for nuke ops
discount *= 0.5
A.cost = max(round(A.cost * discount),1)
A.category = "Discounted Gear"
A.name += " ([round(((initial(A.cost)-A.cost)/initial(A.cost))*100)]% off!)"
A.desc += " Normally costs [initial(A.cost)] TC. All sales final. [pick(disclaimer)]"
A.item = I.item
if(!filtered_uplink_items[A.category])
filtered_uplink_items[A.category] = list()
filtered_uplink_items[A.category][A.name] = A
return filtered_uplink_items
@@ -359,6 +359,12 @@
if(G.can_climax)
setArousalLoss(min_arousal)
//Hyper - antag code
if(src.mind.special_role == ROLE_LEWD_TRAITOR)
for(var/datum/objective/obj in src.mind.objectives)
if (L.mind == obj.target)
L.mind.sexed = TRUE //sexed
to_chat(src, "<span class='userlove'>You feel deep satisfaction with yourself.</span>")
if(impreg)
//Role them odds, only people with the dicks can send the chance to the person with the settings enabled at the momment.
@@ -23,6 +23,9 @@
var/hound_sleeper = TRUE
var/cit_toggles = TOGGLES_CITADEL
//Hyper prefs
var/noncon = FALSE //Definitely want this off by default
// stuff that was in base
max_save_slots = 20
+1
View File
@@ -2891,6 +2891,7 @@
#include "code\modules\VR\vr_sleeper.dm"
#include "code\modules\zombie\items.dm"
#include "code\modules\zombie\organs.dm"
#include "hyperstation\code\gamemode\traitor_lewd.dm"
#include "hyperstation\code\gamemode\werewolf\werewolf.dm"
#include "hyperstation\code\mobs\hugbot.dm"
#include "hyperstation\code\mobs\mimic.dm"