Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into proc-define-shit

This commit is contained in:
SandPoot
2024-03-08 19:10:22 -03:00
810 changed files with 140372 additions and 5523 deletions
+1 -1
View File
@@ -173,7 +173,7 @@
AH.Resolve() //with prejudice
if(banned_client && banned_client.ckey == ckey)
qdel(banned_client)
return 1
return TRUE
/datum/admins/proc/DB_ban_unban(ckey, bantype, job = "")
+12 -12
View File
@@ -7,7 +7,7 @@ GLOBAL_PROTECT(Banlist)
if(!GLOB.Banlist) // if Banlist cannot be located for some reason
LoadBans() // try to load the bans
if(!GLOB.Banlist) // uh oh, can't find bans!
return 0 // ABORT ABORT ABORT
return FALSE // ABORT ABORT ABORT
. = list()
var/appeal
@@ -20,7 +20,7 @@ GLOBAL_PROTECT(Banlist)
if (GLOB.Banlist["temp"])
if (!GetExp(GLOB.Banlist["minutes"]))
ClearTempbans()
return 0
return FALSE
else
.["desc"] = "\nReason: [GLOB.Banlist["reason"]]\nExpires: [GetExp(GLOB.Banlist["minutes"])]\nBy: [GLOB.Banlist["bannedby"]] during round ID [GLOB.Banlist["roundid"]][appeal]"
else
@@ -47,18 +47,18 @@ GLOBAL_PROTECT(Banlist)
if(GLOB.Banlist["temp"])
if (!GetExp(GLOB.Banlist["minutes"]))
ClearTempbans()
return 0
return FALSE
else
.["desc"] = "\nReason: [GLOB.Banlist["reason"]]\nExpires: [GetExp(GLOB.Banlist["minutes"])]\nBy: [GLOB.Banlist["bannedby"]] during round ID [GLOB.Banlist["roundid"]][appeal]"
else
.["desc"] = "\nReason: [GLOB.Banlist["reason"]]\nExpires: <B>PERMENANT</B>\nBy: [GLOB.Banlist["bannedby"]] during round ID [GLOB.Banlist["roundid"]][appeal]"
.["reason"] = matches
return .
return 0
return FALSE
/proc/UpdateTime() //No idea why i made this a proc.
GLOB.CMinutes = (world.realtime / 10) / 60
return 1
return TRUE
/proc/LoadBans()
if(!CONFIG_GET(flag/ban_legacy_system))
@@ -78,7 +78,7 @@ GLOBAL_PROTECT(Banlist)
GLOB.Banlist.cd = "/base"
ClearTempbans()
return 1
return TRUE
/proc/ClearTempbans()
UpdateTime()
@@ -97,7 +97,7 @@ GLOBAL_PROTECT(Banlist)
if (GLOB.CMinutes >= GLOB.Banlist["minutes"])
RemoveBan(A)
return 1
return TRUE
/proc/AddBan(key, computerid, reason, bannedby, temp, minutes, address)
@@ -111,7 +111,7 @@ GLOBAL_PROTECT(Banlist)
GLOB.Banlist.cd = "/base"
if ( GLOB.Banlist.dir.Find("[ban_ckey][computerid]") )
to_chat(usr, text("<span class='danger'>Ban already exists.</span>"))
return 0
return FALSE
else
GLOB.Banlist.dir.Add("[ban_ckey][computerid]")
GLOB.Banlist.cd = "/base/[ban_ckey][computerid]"
@@ -128,7 +128,7 @@ GLOBAL_PROTECT(Banlist)
create_message("note", key, bannedby, "Permanently banned - [reason]", null, null, 0, 0, null, 0, 0)
else
create_message("note", key, bannedby, "Banned for [minutes] minutes - [reason]", null, null, 0, 0, null, 0, 0)
return 1
return TRUE
/proc/RemoveBan(foldername)
var/key
@@ -140,7 +140,7 @@ GLOBAL_PROTECT(Banlist)
GLOB.Banlist.cd = "/base"
if (!GLOB.Banlist.dir.Remove(foldername))
return 0
return FALSE
if(!usr)
log_admin_private("Ban Expired: [key]")
@@ -157,13 +157,13 @@ GLOBAL_PROTECT(Banlist)
GLOB.Banlist.dir.Remove(A)
continue
return 1
return TRUE
/proc/GetExp(minutes as num)
UpdateTime()
var/exp = minutes - GLOB.CMinutes
if (exp <= 0)
return 0
return FALSE
else
var/timeleftstring
if (exp >= 1440) //1440 = 1 day in minutes
+1 -1
View File
@@ -22,7 +22,7 @@
else
logs_missing += "[subject] (empty)"
var/list/combined = sortList(logs_present) + sortList(logs_missing)
var/list/combined = sort_list(logs_present) + sort_list(logs_missing)
var/selected = input("Investigate what?", "Investigate") as null|anything in combined
+7 -5
View File
@@ -18,6 +18,7 @@ GLOBAL_PROTECT(admin_verbs_default)
/client/proc/cmd_admin_pm_panel, /*admin-pm list*/
/client/proc/stop_sounds,
/client/proc/mark_datum_mapview,
/client/proc/tag_datum_mapview,
/client/proc/debugstatpanel
// /client/proc/fix_air /*resets air in designated radius to its default atmos composition*/
)
@@ -88,7 +89,8 @@ GLOBAL_PROTECT(admin_verbs_admin)
/client/proc/addbunkerbypass, //CIT
/client/proc/revokebunkerbypass, //CIT
/datum/admins/proc/open_borgopanel,
/datum/admins/proc/change_laws //change AI laws
/datum/admins/proc/change_laws, //change AI laws
/datum/admins/proc/display_tags,
)
GLOBAL_LIST_INIT(admin_verbs_ban, list(/client/proc/unban_panel, /client/proc/DB_ban_panel, /client/proc/stickybanpanel))
GLOBAL_PROTECT(admin_verbs_ban)
@@ -692,7 +694,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
// if(!SStrading_card_game.loaded)
// message_admins("The card subsystem is not currently loaded")
// return
// var/pack = input("Which pack should we test?", "You fucked it didn't you") as null|anything in sortList(SStrading_card_game.card_packs)
// var/pack = input("Which pack should we test?", "You fucked it didn't you") as null|anything in sort_list(SStrading_card_game.card_packs)
// var/batchCount = input("How many times should we open it?", "Don't worry, I understand") as null|num
// var/batchSize = input("How many cards per batch?", "I hope you remember to check the validation") as null|num
// var/guar = input("Should we use the pack's guaranteed rarity? If so, how many?", "We've all been there. Man you should have seen the old system") as null|num
@@ -712,7 +714,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
var/type_length = length_char("/obj/effect/proc_holder/spell") + 2
for(var/A in GLOB.spells)
spell_list[copytext_char("[A]", type_length)] = A
var/obj/effect/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in sortList(spell_list)
var/obj/effect/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in sort_list(spell_list)
if(!S)
return
@@ -733,7 +735,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
set desc = "Remove a spell from the selected mob."
if(T?.mind)
var/obj/effect/proc_holder/spell/S = input("Choose the spell to remove", "NO ABRAKADABRA") as null|anything in sortList(T.mind.spell_list)
var/obj/effect/proc_holder/spell/S = input("Choose the spell to remove", "NO ABRAKADABRA") as null|anything in sort_list(T.mind.spell_list)
if(S)
T.mind.RemoveSpell(S)
log_admin("[key_name(usr)] removed the spell [S] from [key_name(T)].")
@@ -747,7 +749,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
if(!istype(T))
to_chat(src, "<span class='notice'>You can only give a disease to a mob of type /mob/living.</span>", confidential = TRUE)
return
var/datum/disease/D = input("Choose the disease to give to that guy", "ACHOO") as null|anything in sortList(SSdisease.diseases, GLOBAL_PROC_REF(cmp_typepaths_asc))
var/datum/disease/D = input("Choose the disease to give to that guy", "ACHOO") as null|anything in sort_list(SSdisease.diseases, GLOBAL_PROC_REF(cmp_typepaths_asc))
if(!D)
return
T.ForceContractDisease(new D, FALSE, TRUE)
+2 -2
View File
@@ -29,7 +29,7 @@
if ("Instant Runoff Voting")
polltype = POLLTYPE_IRV
else
return 0
return FALSE
var/starttime = SQLtime()
var/endtime = input("Set end time for poll as format YYYY-MM-DD HH:MM:SS. All times in server time. HH:MM:SS is optional and 24-hour. Must be later than starting time for obvious reasons.", "Set end time", SQLtime()) as text
if(!endtime)
@@ -117,7 +117,7 @@
if("Finish")
add_option = 0
else
return 0
return FALSE
var/m1 = "[key_name(usr)] has created a new server poll. Poll type: [polltype] - Admin Only: [adminonly ? "Yes" : "No"] - Question: [question]"
var/m2 = "[key_name_admin(usr)] has created a new server poll. Poll type: [polltype] - Admin Only: [adminonly ? "Yes" : "No"]<br>Question: [question]"
var/datum/db_query/query_polladd_question = SSdbcore.NewQuery({"
+16 -13
View File
@@ -30,6 +30,9 @@ GLOBAL_PROTECT(href_token)
var/datum/filter_editor/filteriffic
/// A lazylist of tagged datums, for quick reference with the View Tags verb
var/list/tagged_datums
/datum/admins/CanProcCall(procname)
. = ..()
if(!check_rights(R_SENSITIVE))
@@ -137,21 +140,21 @@ GLOBAL_PROTECT(href_token)
/datum/admins/proc/check_for_rights(rights_required)
if(rights_required && !(rights_required & rank.rights))
return 0
return 1
return FALSE
return TRUE
/datum/admins/proc/check_if_greater_rights_than_holder(datum/admins/other)
if(!other)
return 1 //they have no rights
return TRUE //they have no rights
if(rank.rights == R_EVERYTHING)
return 1 //we have all the rights
return TRUE //we have all the rights
if(src == other)
return 1 //you always have more rights than yourself
return TRUE //you always have more rights than yourself
if(rank.rights != other.rank.rights)
if( (rank.rights & other.rank.rights) == other.rank.rights )
return 1 //we have all the rights they have and more
return 0
return TRUE //we have all the rights they have and more
return FALSE
/datum/admins/vv_edit_var(var_name, var_value)
if(var_name == NAMEOF(src, fakekey))
@@ -161,7 +164,7 @@ GLOBAL_PROTECT(href_token)
/*
checks if usr is an admin with at least ONE of the flags in rights_required. (Note, they don't need all the flags)
if rights_required == 0, then it simply checks if they are an admin.
if it doesn't return 1 and show_msg=1 it will prints a message explaining why the check has failed
if it doesn't return TRUE and show_msg=1 it will prints a message explaining why the check has failed
generally it would be used like so:
/proc/admin_proc()
@@ -175,26 +178,26 @@ you will have to do something like if(client.rights & R_ADMIN) yourself.
/proc/check_rights(rights_required, show_msg=1)
if(usr && usr.client)
if (check_rights_for(usr.client, rights_required))
return 1
return TRUE
else
if(show_msg)
to_chat(usr, "<font color='red'>Error: You do not have sufficient rights to do that. You require one of the following flags:[rights2text(rights_required," ")].</font>")
return 0
return FALSE
//probably a bit iffy - will hopefully figure out a better solution
/proc/check_if_greater_rights_than(client/other)
if(usr && usr.client)
if(usr.client.holder)
if(!other || !other.holder)
return 1
return TRUE
return usr.client.holder.check_if_greater_rights_than_holder(other.holder)
return 0
return FALSE
//This proc checks whether subject has at least ONE of the rights specified in rights_required.
/proc/check_rights_for(client/subject, rights_required)
if(subject && subject.holder)
return subject.holder.check_for_rights(rights_required)
return 0
return FALSE
/proc/GenerateToken()
. = ""
+1 -1
View File
@@ -32,7 +32,7 @@
clients += list(client)
clients = sortList(clients, GLOBAL_PROC_REF(cmp_playtime))
clients = sort_list(clients, GLOBAL_PROC_REF(cmp_playtime))
data["clients"] = clients
return data
+1 -1
View File
@@ -81,7 +81,7 @@
var/new_label = stripped_input(user, "Choose a new label.", "Sound Emitter")
if(!new_label)
return
maptext = new_label
maptext = MAPTEXT(new_label)
to_chat(user, "<span class='notice'>Label set to [maptext].</span>", confidential = TRUE)
if(href_list["edit_sound_file"])
var/new_file = input(user, "Choose a sound file.", "Sound Emitter") as null|sound
+1 -1
View File
@@ -403,7 +403,7 @@
if (SSstickyban.dbcacheexpire)
return SSstickyban.dbcache.Copy()
return sortList(world.GetConfig("ban"))
return sort_list(world.GetConfig("ban"))
/proc/get_stickyban_from_ckey(ckey)
+132
View File
@@ -0,0 +1,132 @@
/**
* Inserts the target_datum into [/datum/admins/var/tagged_datums], for later reference.
*
* Arguments:
* * target_datum - The datum you want to create a tag for
*/
/datum/admins/proc/add_tagged_datum(datum/target_datum)
if(LAZYFIND(tagged_datums, target_datum))
to_chat(owner, span_warning("[target_datum] is already tagged!"))
return
LAZYADD(tagged_datums, target_datum)
RegisterSignal(target_datum, COMSIG_PARENT_QDELETING, .proc/handle_tagged_del, override = TRUE)
to_chat(owner, span_notice("[target_datum] has been tagged."))
/// Get ahead of the curve with deleting
/datum/admins/proc/handle_tagged_del(datum/source)
SIGNAL_HANDLER
// No point, we don't even care about it anymore.
if(!LAZYFIND(tagged_datums, source))
return
if(owner)
to_chat(owner, span_boldnotice("Tagged datum [source] ([source.type]) has been deleted."))
remove_tagged_datum(source, silent = TRUE)
/**
* Attempts to remove the specified datum from [/datum/admins/var/tagged_datums] if it exists
*
* Arguments:
* * target_datum - The datum you want to remove from the tagged_datums list
* * silent - If TRUE, won't print messages to the owner's chat
*/
/datum/admins/proc/remove_tagged_datum(datum/target_datum, silent=FALSE)
if(!istype(target_datum))
return
if(LAZYFIND(tagged_datums, target_datum))
LAZYREMOVE(tagged_datums, target_datum)
if(!silent)
to_chat(owner, span_notice("[target_datum] has been untagged."))
else if(!silent)
to_chat(owner, span_warning("[target_datum] was not already tagged."))
/// Quick define for readability
#define TAGS_REFRESH "<A href='?src=[REF(src)];[HrefToken(TRUE)];show_tags=1'>Refresh</a>"
#define TAGS_CLEAR "<A href='?src=[REF(src)];[HrefToken(TRUE)];clear_tags=1'>Untag all</a>"
#define TAG_DEL(X) "<b>(<A href='?src=[REF(src)];[HrefToken(TRUE)];del_tag=[REF(X)]'>UNTAG</a>)</b>"
#define TAG_MARK(X) "<b>(<A href='?src=[REF(src)];[HrefToken(TRUE)];mark_datum=[REF(X)]'>MARK</a>)</b>"
#define TAG_SIMPLE_HEALTH(X) "<font color='#ff0000'><b>Health: [X.health]</b></font>"
#define TAG_CARBON_HEALTH(X) "<font color='#ff0000'><b>Health: [X.health]</b></font> (\
<font color='#ff3333'>[X.getBruteLoss()]</font> \
<font color='#ff9933'>[X.getFireLoss()]</font> \
<font color='#00cc66'>[X.getToxLoss()]</font> \
<font color='#00cccc'>[X.getOxyLoss()]</font>\
[X.getCloneLoss() ? " <font color='#1c3ac4'>[X.getCloneLoss()]</font>" : ""])"
/// Display all of the tagged datums
/datum/admins/proc/display_tags()
set category = "Admin.Game"
set name = "View Tags"
if (!istype(src, /datum/admins))
src = usr.client.holder
if (!istype(src, /datum/admins))
to_chat(usr, "Error: you are not an admin!", confidential = TRUE)
return
var/index = 0
var/list/dat = list("<center><B>Tag Menu</B></center><hr>")
dat += "<br>[TAGS_REFRESH] | [TAGS_CLEAR]<br>"
if(LAZYLEN(tagged_datums))
for(var/datum/iter_datum as anything in tagged_datums)
index++
var/specific_info
if(isnull(iter_datum))
dat += "\t[index]: Null reference - Check runtime logs!"
stack_trace("Null datum found in tagged datum menu! User: [usr]")
continue
else if(iscarbon(iter_datum))
var/mob/living/carbon/resolved_carbon = iter_datum
specific_info = "[TAG_CARBON_HEALTH(resolved_carbon)] | [AREACOORD(resolved_carbon)] [ADMIN_PP(iter_datum)] [ADMIN_FLW(iter_datum)]"
else if(isliving(iter_datum))
var/mob/living/resolved_living = iter_datum
specific_info = "[TAG_SIMPLE_HEALTH(resolved_living)] | [AREACOORD(resolved_living)] [ADMIN_PP(iter_datum)] [ADMIN_FLW(iter_datum)]"
else if(ismob(iter_datum))
var/atom/resolved_atom = iter_datum // needed for ADMIN_JMP
specific_info = "[AREACOORD(resolved_atom)] [ADMIN_PP(iter_datum)] [ADMIN_FLW(iter_datum)]"
else if(ismovable(iter_datum))
var/atom/resolved_atom = iter_datum // needed for ADMIN_JMP
specific_info = "[AREACOORD(resolved_atom)] [ADMIN_FLW(iter_datum)]"
else if(isatom(iter_datum))
var/atom/resolved_atom = iter_datum // needed for ADMIN_JMP
specific_info = "[AREACOORD(resolved_atom)] [ADMIN_JMP(resolved_atom)]"
else if(istype(iter_datum, /datum/controller/subsystem))
var/datum/controller/subsystem/resolved_subsystem = iter_datum
specific_info = "[resolved_subsystem.stat_entry()]"
// else, it's just a /datum
dat += "\t[index]: [iter_datum] | [specific_info] | [ADMIN_VV(iter_datum)]| [TAG_DEL(iter_datum)] | [iter_datum == marked_datum ? "<b>Marked</b>" : TAG_MARK(iter_datum)] "
dat += "\t(<b><font size='2'>[iter_datum.type])</font></b>"
else
dat += "No datums tagged :("
dat = dat.Join("<br>")
usr << browse(dat, "window=tag;size=800x480")
/**
* Clears tagged datums
*/
/datum/admins/proc/clear_tags()
var/amount_of_tags = LAZYLEN(tagged_datums)
if(!amount_of_tags)
to_chat(owner, span_warning("There are no tagged datums to clear."))
return
var/confirmation = alert(usr, "Clear your tagged datums? ([amount_of_tags])", "Confirmation", "Yes", "No")
if(confirmation != "Yes")
return
LAZYNULL(tagged_datums)
to_chat(owner, span_notice("Tagged datums have been cleared, [amount_of_tags] item\s removed."))
#undef TAGS_REFRESH
#undef TAGS_CLEAR
#undef TAG_DEL
#undef TAG_MARK
#undef TAG_SIMPLE_HEALTH
#undef TAG_CARBON_HEALTH
+30 -5
View File
@@ -1026,7 +1026,7 @@
to_chat(M, "<span class='boldannounce'>The reason is: [reason]</span>")
to_chat(M, "<span class='danger'>This jobban will be lifted in [mins] minutes.</span>")
href_list["jobban2"] = 1 // lets it fall through and refresh
return 1
return TRUE
if("No")
var/reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null
severity = input("Set the severity of the note/ban.", "Severity", null, null) as null|anything in list("High", "Medium", "Minor", "None")
@@ -1052,7 +1052,7 @@
to_chat(M, "<span class='boldannounce'>The reason is: [reason]</span>")
to_chat(M, "<span class='danger'>Jobban can be lifted only upon request.</span>")
href_list["jobban2"] = 1 // lets it fall through and refresh
return 1
return TRUE
if("Cancel")
return
@@ -1081,8 +1081,8 @@
message_admins("<span class='adminnotice'>[key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg].</span>")
to_chat(M, "<span class='boldannounce'><BIG>You have been un-jobbanned by [usr.client.key] from [msg].</BIG></span>")
href_list["jobban2"] = 1 // lets it fall through and refresh
return 1
return 0 //we didn't do anything!
return TRUE
return FALSE //we didn't do anything!
else if(href_list["boot2"])
if(!check_rights(R_ADMIN))
@@ -1351,7 +1351,7 @@
for (var/rule in subtypesof(/datum/dynamic_ruleset/roundstart))
var/datum/dynamic_ruleset/roundstart/newrule = new rule()
roundstart_rules[newrule.name] = newrule
var/added_rule = input(usr,"What ruleset do you want to force? This will bypass threat level and population restrictions.", "Rigging Roundstart", null) as null|anything in sortList(roundstart_rules)
var/added_rule = input(usr,"What ruleset do you want to force? This will bypass threat level and population restrictions.", "Rigging Roundstart", null) as null|anything in sort_list(roundstart_rules)
if (added_rule)
GLOB.dynamic_forced_roundstart_ruleset += roundstart_rules[added_rule]
log_admin("[key_name(usr)] set [added_rule] to be a forced roundstart ruleset.")
@@ -2705,6 +2705,31 @@
log_query_debug("[usr.key] | [response]")
else if(answer == "no")
log_query_debug("[usr.key] | Reported no server hang")
else if(href_list["del_tag"])
if(!check_rights(R_ADMIN))
return
var/datum/datum_to_remove = locate(href_list["del_tag"])
if(!datum_to_remove)
return
return remove_tagged_datum(datum_to_remove)
else if(href_list["show_tags"])
if(!check_rights(R_ADMIN))
return
return display_tags()
else if(href_list["clear_tags"])
if(!check_rights(R_ADMIN))
return
return clear_tags()
else if(href_list["mark_datum"])
if(!check_rights(R_ADMIN))
return
var/datum/datum_to_mark = locate(href_list["mark_datum"])
if(!datum_to_mark)
return
return usr.client?.mark_datum(datum_to_mark)
/datum/admins/proc/HandleCMode()
if(!check_rights(R_ADMIN))
+1 -1
View File
@@ -30,7 +30,7 @@
targets["[T.mob.real_name](as [T.mob.name]) - [T]"] = T
else
targets["(No Mob) - [T]"] = T
var/target = input(src,"To whom shall we send a message?","Admin PM",null) as null|anything in sortList(targets)
var/target = input(src,"To whom shall we send a message?","Admin PM",null) as null|anything in sort_list(targets)
cmd_admin_pm(targets[target],null)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Admin PM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+57 -17
View File
@@ -50,15 +50,12 @@
"lockdown" = borg.locked_down,
"scrambledcodes" = borg.scrambledcodes
)
.["upgrades"] = list()
for (var/upgradetype in subtypesof(/obj/item/borg/upgrade)-/obj/item/borg/upgrade/hypospray) //hypospray is a dummy parent for hypospray upgrades
var/obj/item/borg/upgrade/upgrade = upgradetype
if (initial(upgrade.module_type) && !is_type_in_list(borg.module, initial(upgrade.module_type))) // Upgrade requires a different module
continue
var/installed = FALSE
if (locate(upgradetype) in borg)
installed = TRUE
.["upgrades"] += list(list("name" = initial(upgrade.name), "installed" = installed, "type" = upgradetype))
var/obj/item/gun/energy/kinetic_accelerator/kinetic_accelerator = locate(/obj/item/gun/energy/kinetic_accelerator) in borg.module
if(kinetic_accelerator)
.["ka_remaining_capacity"] = kinetic_accelerator.get_remaining_mod_capacity()
.["active_upgrades"] = list()
for (var/obj/item/borg/upgrade/upgrade as anything in borg.upgrades) // put a non-upgrade here, i dare you.
.["active_upgrades"] += list(list("type" = upgrade.type))
.["laws"] = borg.laws ? borg.laws.get_law_list(include_zeroth = TRUE, render_html = FALSE) : list()
.["channels"] = list()
for (var/k in GLOB.radiochannels)
@@ -77,6 +74,28 @@
for(var/mob/living/silicon/ai/ai in GLOB.ai_list)
.["ais"] += list(list("name" = ai.name, "ref" = REF(ai), "connected" = (borg.connected_ai == ai)))
/datum/borgpanel/ui_static_data(mob/user)
. = ..()
.["upgrades"] = list()
for(var/obj/item/borg/upgrade/upgrade as anything in GLOB.borg_upgrades)
if(upgrade.type == upgrade.abstract_type)
continue
var/obj/item/borg/upgrade/modkit/modkit
if(istype(upgrade, /obj/item/borg/upgrade/modkit))
modkit = upgrade
if(modkit.minebot_exclusive)
continue
modkit = upgrade
.["upgrades"] += list(
list(
"name" = upgrade.name,
"type" = upgrade.type,
"module_type" = upgrade.module_type,
"maximum_of_type" = modkit ? modkit.maximum_of_type : null,
"denied_type" = modkit ? modkit.denied_type : null,
"cost" = modkit ? modkit.cost : null
)
)
/datum/borgpanel/ui_act(action, params)
if(..())
@@ -148,17 +167,31 @@
var/upgradepath = text2path(params["upgrade"])
var/obj/item/borg/upgrade/installedupgrade = locate(upgradepath) in borg
if (installedupgrade)
installedupgrade.deactivate(borg, user)
borg.upgrades -= installedupgrade
qdel(installedupgrade)
message_admins("[key_name_admin(user)] removed the [installedupgrade] upgrade from [ADMIN_LOOKUPFLW(borg)].")
log_admin("[key_name(user)] removed the [installedupgrade] upgrade from [key_name(borg)].")
qdel(installedupgrade)
else
var/obj/item/borg/upgrade/upgrade = new upgradepath(borg)
upgrade.action(borg, user)
borg.upgrades += upgrade
var/obj/item/borg/upgrade/upgrade = new upgradepath()
if(!borg.apply_upgrade(upgrade, user, TRUE))
to_chat(user, span_danger("Upgrade error."))
return
message_admins("[key_name_admin(user)] added the [upgrade] borg upgrade to [ADMIN_LOOKUPFLW(borg)].")
log_admin("[key_name(user)] added the [upgrade] borg upgrade to [key_name(borg)].")
if ("add_upgrade")
var/upgradepath = text2path(params["upgrade"])
var/obj/item/borg/upgrade/upgrade = new upgradepath()
if(!borg.apply_upgrade(upgrade, user, TRUE))
to_chat(user, span_danger("Upgrade error."))
return
message_admins("[key_name_admin(user)] added the [upgrade] borg upgrade to [ADMIN_LOOKUPFLW(borg)].")
log_admin("[key_name(user)] added the [upgrade] borg upgrade to [key_name(borg)].")
if ("remove_upgrade")
var/upgradepath = text2path(params["upgrade"])
var/obj/item/borg/upgrade/installedupgrade = locate(upgradepath) in borg
if (installedupgrade)
qdel(installedupgrade)
message_admins("[key_name_admin(user)] removed the [installedupgrade] upgrade from [ADMIN_LOOKUPFLW(borg)].")
log_admin("[key_name(user)] removed the [installedupgrade] upgrade from [key_name(borg)].")
if ("toggle_radio")
var/channel = params["channel"]
if (channel in borg.radio.channels) // We're removing a channel
@@ -226,13 +259,20 @@
if (!istype(chosensilicon, /mob/living/silicon))
to_chat(usr, "<span class='warning'>Silicon is required for law changes</span>", confidential=TRUE)
return
var/chosen = pick_closest_path(null, make_types_fancy(typesof(/obj/item/aiModule)))
var/chosen = pick_closest_path(null, make_types_fancy(typesof(/obj/item/ai_module)))
if (!chosen)
return
var/new_board = new chosen(src)
var/obj/item/aiModule/chosenboard = new_board
var/obj/item/ai_module/chosenboard = new_board
var/mob/living/silicon/beepboop = chosensilicon
chosenboard.install(beepboop.laws, usr)
message_admins("[key_name_admin(usr)] added [chosenboard] to [ADMIN_LOOKUPFLW(beepboop)].")
log_admin("[key_name(usr)] added [chosenboard] to [key_name(beepboop)].")
qdel(new_board)
GLOBAL_LIST_INIT(borg_upgrades, populate_borg_upgrades())
/proc/populate_borg_upgrades()
. = list()
for(var/type in typesof(/obj/item/borg/upgrade))
. += new type
+10 -10
View File
@@ -89,11 +89,11 @@
available.Add(C)
var/mob/choice = input("Choose a player to play the pAI", "Spawn pAI") in available
if(!choice)
return 0
return FALSE
if(!isobserver(choice))
var/confirm = input("[choice.key] isn't ghosting right now. Are you sure you want to yank him out of them out of their body and place them in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
if(confirm != "Yes")
return 0
return FALSE
var/obj/item/paicard/card = new(T)
var/mob/living/silicon/pai/pai = new(card)
pai.name = input(choice, "Enter your pAI name:", "pAI Name", "Personal AI") as text
@@ -238,7 +238,7 @@
if(M.ckey)
if(alert("This mob is being controlled by [M.key]. Are you sure you wish to give someone else control of it? [M.key] will be made a ghost.",,"Yes","No") != "Yes")
return
var/client/newkey = input(src, "Pick the player to put in control.", "New player") as null|anything in sortList(GLOB.clients)
var/client/newkey = input(src, "Pick the player to put in control.", "New player") as null|anything in sort_list(GLOB.clients)
var/mob/oldmob = newkey.mob
var/delmob = FALSE
if((isobserver(oldmob) || alert("Do you want to delete [newkey]'s old mob?","Delete?","Yes","No") != "No"))
@@ -494,7 +494,7 @@
var/datum/outfit/O = path //not much to initalize here but whatever
outfits[initial(O.name)] = path
var/dresscode = input("Select outfit", "Robust quick dress shop") as null|anything in baseoutfits + sortList(outfits)
var/dresscode = input("Select outfit", "Robust quick dress shop") as null|anything in baseoutfits + sort_list(outfits)
if (isnull(dresscode))
return
@@ -508,7 +508,7 @@
var/datum/outfit/O = path
job_outfits[initial(O.name)] = path
dresscode = input("Select job equipment", "Robust quick dress shop") as null|anything in sortList(job_outfits)
dresscode = input("Select job equipment", "Robust quick dress shop") as null|anything in sort_list(job_outfits)
dresscode = job_outfits[dresscode]
if(isnull(dresscode))
return
@@ -520,7 +520,7 @@
var/datum/outfit/O = path
plasmaman_outfits[initial(O.name)] = path
dresscode = input("Select plasmeme equipment", "Robust quick dress shop") as null|anything in sortList(plasmaman_outfits)
dresscode = input("Select plasmeme equipment", "Robust quick dress shop") as null|anything in sort_list(plasmaman_outfits)
dresscode = plasmaman_outfits[dresscode]
if(isnull(dresscode))
return
@@ -529,7 +529,7 @@
var/list/custom_names = list()
for(var/datum/outfit/D in GLOB.custom_outfits)
custom_names[D.name] = D
var/selected_name = input("Select outfit", "Robust quick dress shop") as null|anything in sortList(custom_names)
var/selected_name = input("Select outfit", "Robust quick dress shop") as null|anything in sort_list(custom_names)
dresscode = custom_names[selected_name]
if(isnull(dresscode))
return
@@ -828,15 +828,15 @@
set name = "Show Line Profiling"
set desc = "Shows tracked profiling info from code lines that support it"
var/sortlist = list(
var/sort_list = list(
"Avg time" = GLOBAL_PROC_REF(cmp_profile_avg_time_dsc),
"Total Time" = GLOBAL_PROC_REF(cmp_profile_time_dsc),
"Call Count" = GLOBAL_PROC_REF(cmp_profile_count_dsc)
)
var/sort = input(src, "Sort type?", "Sort Type", "Avg time") as null|anything in sortlist
var/sort = input(src, "Sort type?", "Sort Type", "Avg time") as null|anything in sort_list
if (!sort)
return
sort = sortlist[sort]
sort = sort_list[sort]
profile_show(src, sort)
/client/proc/reload_configuration()
+3 -3
View File
@@ -65,7 +65,7 @@ GLOBAL_PROTECT(admin_verbs_debug_mapping)
icon_state = "yellow"
/obj/effect/debugging/marker/Move()
return 0
return FALSE
/client/proc/camera_view()
set category = "Mapping"
@@ -83,7 +83,7 @@ GLOBAL_PROTECT(admin_verbs_debug_mapping)
for(var/turf/T in C.can_see())
seen[T]++
for(var/turf/T in seen)
T.maptext = "[seen[T]]"
T.maptext = MAPTEXT("[seen[T]]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Camera Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Camera Range")
@@ -111,7 +111,7 @@ GLOBAL_LIST_EMPTY(dirty_vars)
if(!Master)
alert(usr,"Master_controller not found.","Sec Camera Report")
return 0
return FALSE
var/list/obj/machinery/camera/CL = list()
+15 -15
View File
@@ -70,10 +70,10 @@
H.mind.make_Traitor()
candidates.Remove(H)
return 1
return TRUE
return 0
return FALSE
/datum/admins/proc/makeChangelings()
@@ -102,9 +102,9 @@
H.mind.make_Changeling()
candidates.Remove(H)
return 1
return TRUE
return 0
return FALSE
/datum/admins/proc/makeRevs()
@@ -131,9 +131,9 @@
H = pick(candidates)
H.mind.make_Rev()
candidates.Remove(H)
return 1
return TRUE
return 0
return FALSE
/datum/admins/proc/makeWizard()
@@ -171,9 +171,9 @@
H.mind.make_Cultist()
candidates.Remove(H)
return 1
return TRUE
return 0
return FALSE
/datum/admins/proc/makeClockCult()
@@ -206,9 +206,9 @@
SSticker.mode.equip_servant(H)
candidates.Remove(H)
return 1
return TRUE
return 0
return FALSE
@@ -236,7 +236,7 @@
break
//Making sure we have atleast 3 Nuke agents, because less than that is kinda bad
if(agentcount < 3)
return 0
return FALSE
//Let's find the spawn locations
var/leader_chosen = FALSE
@@ -249,9 +249,9 @@
nuke_team = N.nuke_team
else
new_character.mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team)
return 1
return TRUE
else
return 0
return FALSE
@@ -451,8 +451,8 @@
//Abductors
/datum/admins/proc/makeAbductorTeam()
new /datum/round_event/ghost_role/abductor
return 1
return TRUE
/datum/admins/proc/makeRevenant()
new /datum/round_event/ghost_role/revenant(TRUE, TRUE)
return 1
return TRUE
+5 -5
View File
@@ -300,7 +300,7 @@
else
to_chat(usr, "<span class='danger'>Error: create_xeno(): no suitable candidates.</span>")
if(!istext(ckey))
return 0
return FALSE
var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Praetorian","Hunter","Sentinel","Drone","Larva")
var/obj/effect/landmark/spawn_here = GLOB.xeno_spawn.len ? pick(GLOB.xeno_spawn) : null
@@ -319,7 +319,7 @@
if("Larva")
new_xeno = new /mob/living/carbon/alien/larva(spawn_here)
else
return 0
return FALSE
if(!spawn_here)
SSjob.SendToLateJoin(new_xeno, FALSE)
@@ -327,7 +327,7 @@
var/msg = "<span class='notice'>[key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].</span>"
message_admins(msg)
admin_ticket_log(new_xeno, msg)
return 1
return TRUE
/*
If a guy was gibbed and you want to revive him, this is a good way to do so.
@@ -1672,7 +1672,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/name = GLOB.trait_name_map[trait] || trait
availible_traits[name] = trait
var/chosen_trait = input("Select trait to modify", "Trait") as null|anything in sortList(availible_traits)
var/chosen_trait = input("Select trait to modify", "Trait") as null|anything in sort_list(availible_traits)
if(!chosen_trait)
return
chosen_trait = availible_traits[chosen_trait]
@@ -1689,7 +1689,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if("All")
source = null
if("Specific")
source = input("Source to be removed","Trait Remove/Add") as null|anything in sortList(D.status_traits[chosen_trait])
source = input("Source to be removed","Trait Remove/Add") as null|anything in sort_list(D.status_traits[chosen_trait])
if(!source)
return
REMOVE_TRAIT(D,chosen_trait,source)
+1 -1
View File
@@ -246,7 +246,7 @@
var/datum/round_event_control/disease_outbreak/DC = locate(/datum/round_event_control/disease_outbreak) in SSevents.control
E = DC.runEvent()
if("Choose")
var/virus = input("Choose the virus to spread", "BIOHAZARD") as null|anything in sortList(typesof(/datum/disease), GLOBAL_PROC_REF(cmp_typepaths_asc))
var/virus = input("Choose the virus to spread", "BIOHAZARD") as null|anything in sort_list(typesof(/datum/disease), GLOBAL_PROC_REF(cmp_typepaths_asc))
var/datum/round_event_control/disease_outbreak/DC = locate(/datum/round_event_control/disease_outbreak) in SSevents.control
var/datum/round_event/disease_outbreak/DO = DC.runEvent()
DO.virus_type = virus
@@ -77,6 +77,15 @@
markstring = "[VV_MARKED_DATUM] (CURRENT: [(istype(holder) && istype(holder.marked_datum))? holder.marked_datum.type : "NULL"])"
classes += markstring
var/list/tagstrings = new
if(!(VV_TAGGED_DATUM in restricted_classes) && holder && LAZYLEN(holder.tagged_datums))
var/i = 0
for(var/datum/iter_tagged_datum as anything in holder.tagged_datums)
i++
var/new_tagstring = "[VV_TAGGED_DATUM] #[i]: [iter_tagged_datum.type])"
tagstrings[new_tagstring] = iter_tagged_datum
classes += new_tagstring
if(restricted_classes)
classes -= restricted_classes
@@ -87,6 +96,11 @@
if(holder && holder.marked_datum && .["class"] == markstring)
.["class"] = VV_MARKED_DATUM
if(holder && tagstrings[.["class"]])
var/datum/chosen_datum = tagstrings[.["class"]]
.["value"] = chosen_datum
.["class"] = VV_TAGGED_DATUM
switch(.["class"])
if(VV_TEXT)
.["value"] = input("Enter new text:", "Text", current_value) as null|text
@@ -202,6 +216,11 @@
.["class"] = null
return
if(VV_TAGGED_DATUM)
if(.["value"] == null)
.["class"] = null
return
if(VV_PROCCALL_RETVAL)
var/list/get_retval = list()
callproc_blocking(get_retval)
@@ -29,7 +29,7 @@
for (var/V in O.vars)
names += V
names = sortList(names)
names = sort_list(names)
variable = input("Which var?", "Var") as null|anything in names
else
@@ -306,7 +306,7 @@ GLOBAL_PROTECT(VVpixelmovement)
for (var/V in O.vars)
names += V
names = sortList(names)
names = sort_list(names)
variable = input("Which var?","Var") as null|anything in names
if(!variable)
@@ -0,0 +1,18 @@
/client/proc/tag_datum(datum/target_datum)
if(!holder || QDELETED(target_datum))
return
holder.add_tagged_datum(target_datum)
/client/proc/toggle_tag_datum(datum/target_datum)
if(!holder || !target_datum)
return
if(LAZYFIND(holder.tagged_datums, target_datum))
holder.remove_tagged_datum(target_datum)
else
holder.add_tagged_datum(target_datum)
/client/proc/tag_datum_mapview(datum/target_datum as mob|obj|turf|area in view(view))
set category = "Debug"
set name = "Tag Datum"
tag_datum(target_datum)
@@ -59,15 +59,17 @@
if(href_list[VV_HK_MARK])
usr.client.mark_datum(target)
if(href_list[VV_HK_TAG])
usr.client.tag_datum(target)
if(href_list[VV_HK_ADDCOMPONENT])
if(!check_rights(NONE))
return
var/list/names = list()
var/list/componentsubtypes = sortList(subtypesof(/datum/component), GLOBAL_PROC_REF(cmp_typepaths_asc))
var/list/componentsubtypes = sort_list(subtypesof(/datum/component), GLOBAL_PROC_REF(cmp_typepaths_asc))
names += "---Components---"
names += componentsubtypes
names += "---Elements---"
names += sortList(subtypesof(/datum/element), GLOBAL_PROC_REF(cmp_typepaths_asc))
names += sort_list(subtypesof(/datum/element), GLOBAL_PROC_REF(cmp_typepaths_asc))
var/result = input(usr, "Choose a component/element to add","better know what ur fuckin doin pal") as null|anything in names
if(!usr || !result || result == "---Components---" || result == "---Elements---")
return
@@ -88,7 +88,7 @@
value = L[key]
variable_html += debug_variable(i, value, 0, L)
else
names = sortList(names)
names = sort_list(names)
for(var/V in names)
if(D.can_vv_get(V))
variable_html += D.vv_get_var(V)
@@ -449,7 +449,7 @@ GLOBAL_LIST_EMPTY(antagonists)
antag_memory = new_memo
/**
* Gets how fast we can hijack the shuttle, return 0 for can not hijack.
* Gets how fast we can hijack the shuttle, return FALSE for can not hijack.
* Defaults to hijack_speed var, override for custom stuff like buffing hijack speed for hijack objectives or something.
*/
/datum/antagonist/proc/hijack_speed()
@@ -50,7 +50,7 @@
if(H.stat || H.restrained())
return
if(!ishuman(H))
return 1
return TRUE
if(loc == H || (in_range(src, H) && isturf(loc)))
H.set_machine(src)
@@ -59,7 +59,7 @@
H.update_inv_wear_suit()
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
A.UpdateButtons()
/obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == ITEM_SLOT_OCLOTHING) //we only give the mob the ability to activate the vest if he's actually wearing it.
@@ -61,7 +61,7 @@
/datum/station_state/proc/score(datum/station_state/result)
if(!result)
return 0
return FALSE
var/output = 0
output += (result.floor / max(floor,1))
output += (result.r_wall/ max(r_wall,1))
@@ -53,7 +53,7 @@
/mob/living/simple_animal/hostile/blob/Process_Spacemove(movement_dir = 0)
for(var/obj/structure/blob/B in range(1, src))
return 1
return TRUE
return ..()
/mob/living/simple_animal/hostile/blob/proc/blob_chat(msg)
@@ -275,7 +275,7 @@
/mob/living/simple_animal/hostile/blob/blobbernaut/update_health_hud()
if(hud_used)
hud_used.healths.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#e36600'>[round((health / maxHealth) * 100, 0.5)]%</font></div>"
hud_used.healths.maptext = MAPTEXT("<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#e36600'>[round((health / maxHealth) * 100, 0.5)]%</font></div>")
/mob/living/simple_animal/hostile/blob/blobbernaut/AttackingTarget()
. = ..()
@@ -65,7 +65,7 @@ GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/
return
/datum/blobstrain/proc/tesla_reaction(obj/structure/blob/B, power, coefficient = 1) //when the blob is hit by a tesla bolt, do this
return 1 //return 0 to ignore damage
return TRUE //return FALSE to ignore damage
/datum/blobstrain/proc/extinguish_reaction(obj/structure/blob/B, coefficient = 1) //when the blob is hit with water, do this
return
@@ -29,5 +29,5 @@
/datum/reagent/blob/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
return 0 //the dead, and blob mobs, don't cause reactions
return FALSE //the dead, and blob mobs, don't cause reactions
return round(reac_volume * min(1.5 - touch_protection, 1), 0.1) //full touch protection means 50% volume, any prot below 0.5 means 100% volume.
@@ -23,7 +23,7 @@
if(!(C && C.overmind && C.overmind.blobstrain.type == B.overmind.blobstrain.type) && prob(80))
new /obj/effect/hotspot(T)
if(damage_flag == FIRE)
return 0
return FALSE
return ..()
/datum/reagent/blob/blazing_oil
@@ -15,7 +15,7 @@
return ..()
/datum/blobstrain/reagent/energized_jelly/tesla_reaction(obj/structure/blob/B, power)
return 0
return FALSE
/datum/blobstrain/reagent/energized_jelly/emp_reaction(obj/structure/blob/B, severity)
var/damage = rand(30, 50) - severity * rand(10, 15)
@@ -13,7 +13,7 @@
/datum/blobstrain/reagent/explosive_lattice/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
if(damage_flag == BOMB)
return 0
return FALSE
else if(damage_flag != MELEE && damage_flag != BULLET && damage_flag != LASER)
return damage * 1.5
return ..()
@@ -29,7 +29,7 @@
for (var/datum/blobstrain/bt in blobstrains)
. += bt.tesla_reaction(B, power, coefficient*typeshare)
if (prob(. / length(blobstrains) * 100))
return 1
return TRUE
/datum/blobstrain/multiplex/extinguish_reaction(obj/structure/blob/B, coefficient = 1) //when the blob is hit with water, do this
for (var/datum/blobstrain/bt in blobstrains)
@@ -26,5 +26,5 @@
/datum/reagent/blob/reactive_spines/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
return 0 //the dead, and blob mobs, don't cause reactions
return FALSE //the dead, and blob mobs, don't cause reactions
M.adjustBruteLoss(0.8*reac_volume)
@@ -197,14 +197,14 @@ GLOBAL_LIST_EMPTY(blob_nodes)
/mob/camera/blob/update_health_hud()
if(blob_core)
hud_used.healths.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#e36600'>[round(blob_core.obj_integrity)]</font></div>"
hud_used.healths.maptext = MAPTEXT("<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#e36600'>[round(blob_core.obj_integrity)]</font></div>")
for(var/mob/living/simple_animal/hostile/blob/blobbernaut/B in blob_mobs)
if(B.hud_used && B.hud_used.blobpwrdisplay)
B.hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(blob_core.obj_integrity)]</font></div>"
B.hud_used.blobpwrdisplay.maptext = MAPTEXT("<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(blob_core.obj_integrity)]</font></div>")
/mob/camera/blob/proc/add_points(points)
blob_points = clamp(blob_points + points, 0, max_blob_points)
hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(blob_points)]</font></div>"
hud_used.blobpwrdisplay.maptext = MAPTEXT("<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(blob_points)]</font></div>")
/mob/camera/blob/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
if (!message)
@@ -264,13 +264,13 @@ GLOBAL_LIST_EMPTY(blob_nodes)
if(B)
forceMove(NewLoc)
else
return 0
return FALSE
else
var/area/A = get_area(NewLoc)
if(isspaceturf(NewLoc) || istype(A, /area/shuttle)) //if unplaced, can't go on shuttles or space tiles
return 0
return FALSE
forceMove(NewLoc)
return 1
return TRUE
/mob/camera/blob/mind_initialize()
. = ..()
+10 -10
View File
@@ -1,15 +1,15 @@
/mob/camera/blob/proc/can_buy(cost = 15)
if(blob_points < cost)
to_chat(src, "<span class='warning'>You cannot afford this, you need at least [cost] resources!</span>")
return 0
return FALSE
add_points(-cost)
return 1
return TRUE
// Power verbs
/mob/camera/blob/proc/place_blob_core(placement_override, pop_override = FALSE)
if(placed && placement_override != -1)
return 1
return TRUE
if(!placement_override)
if(!pop_override)
for(var/mob/living/M in range(7, src))
@@ -17,30 +17,30 @@
continue
if(M.client)
to_chat(src, "<span class='warning'>There is someone too close to place your blob core!</span>")
return 0
return FALSE
for(var/mob/living/M in view(13, src))
if(ROLE_BLOB in M.faction)
continue
if(M.client)
to_chat(src, "<span class='warning'>Someone could see your blob core from here!</span>")
return 0
return FALSE
var/turf/T = get_turf(src)
if(T.density)
to_chat(src, "<span class='warning'>This spot is too dense to place a blob core on!</span>")
return 0
return FALSE
for(var/obj/O in T)
if(istype(O, /obj/structure/blob))
if(istype(O, /obj/structure/blob/normal))
qdel(O)
else
to_chat(src, "<span class='warning'>There is already a blob here!</span>")
return 0
return FALSE
else if(O.density)
to_chat(src, "<span class='warning'>This spot is too dense to place a blob core on!</span>")
return 0
return FALSE
if(!pop_override && world.time <= manualplace_min_time && world.time <= autoplace_max_time)
to_chat(src, "<span class='warning'>It is too early to place your blob core!</span>")
return 0
return FALSE
else if(placement_override == 1)
var/turf/T = pick(GLOB.blobstart)
forceMove(T) //got overrided? you're somewhere random, motherfucker
@@ -54,7 +54,7 @@
core.update_icon()
update_health_hud()
placed = 1
return 1
return TRUE
/mob/camera/blob/verb/transport_core()
set category = "Blob"
@@ -123,8 +123,8 @@
heal_timestamp = world.time + 20
update_icon()
pulse_timestamp = world.time + 10
return 1 //we did it, we were pulsed!
return 0 //oh no we failed
return TRUE //we did it, we were pulsed!
return FALSE //oh no we failed
/obj/structure/blob/proc/ConsumeTile()
for(var/atom/A in loc)
@@ -157,7 +157,7 @@
else
T = null
if(!T)
return 0
return FALSE
var/make_blob = TRUE //can we make a blob?
if(isspaceturf(T) && !(locate(/obj/structure/lattice) in T) && prob(80))
@@ -271,7 +271,7 @@
damage_amount *= fire_resist
if(CLONE)
else
return 0
return FALSE
var/armor_protection = 0
if(damage_flag)
armor_protection = armor.getRating(damage_flag)
@@ -216,7 +216,7 @@
return
// Disable Powers: Masquerade * NOTE * This should happen as a FLAW!
//if (stat >= UNCONSCIOUS)
// for (var/datum/action/bloodsucker/masquerade/P in powers)
// for (var/datum/action/cooldown/bloodsucker/masquerade/P in powers)
// P.Deactivate()
// TEMP DEATH
var/total_brute = owner.current.getBruteLoss_nonProsthetic()
@@ -252,7 +252,7 @@
owner.current.update_sight()
owner.current.reload_fullscreen()
// Disable ALL Powers
for(var/datum/action/bloodsucker/power in powers)
for(var/datum/action/cooldown/bloodsucker/power in powers)
if(power.active && !power.can_use_in_torpor)
power.DeactivatePower()
if(owner.current.suiciding)
@@ -1,22 +1,26 @@
/datum/action/bloodsucker
/datum/action/cooldown/bloodsucker
name = "Vampiric Gift"
desc = "A vampiric gift."
button_icon = 'icons/mob/actions/bloodsucker.dmi' //This is the file for the BACKGROUND icon
background_icon_state = "vamp_power_off" //And this is the state for the background icon
var/background_icon_state_on = "vamp_power_on" // FULP: Our "ON" icon alternative.
var/background_icon_state_off = "vamp_power_off" // FULP: Our "OFF" icon alternative.
icon_icon = 'icons/mob/actions/bloodsucker.dmi' //This is the file for the ACTION icon
button_icon_state = "power_feed" //And this is the state for the action icon
buttontooltipstyle = "cult"
transparent_when_unavailable = TRUE
/// Cooldown you'll have to wait between each use, decreases depending on level.
cooldown_time = 2 SECONDS
///Background icon when the Power is active.
var/background_icon_state_on = "vamp_power_on"
///Background icon when the Power is NOT active.
var/background_icon_state_off = "vamp_power_off"
// Action-Related
//var/amPassive = FALSE // REMOVED: Just made it its own kind. // Am I just "on" at all times? (aka NO ICON)
var/amTargetted = FALSE // Am I asked to choose a target when enabled? (Shows as toggled ON when armed)
var/amToggle = FALSE // Can I be actively turned on and off?
var/amSingleUse = FALSE // Am I removed after a single use?
var/active = FALSE
var/cooldown = 20 // 10 ticks, 1 second.
var/cooldownUntil = 0 // From action.dm: next_use_time = world.time + cooldown_time
// Power-Related
var/level_current = 0 // Can increase to yield new abilities. Each power goes up in strength each Rank.
//var/level_max = 1 //
@@ -32,7 +36,7 @@
//var/not_bloodsucker = FALSE // This goes to Vassals or Hunters, but NOT bloodsuckers.
var/must_be_concious = TRUE //Can't use this ability while unconcious.
/datum/action/bloodsucker/New()
/datum/action/cooldown/bloodsucker/New()
if(bloodcost > 0)
desc += "<br><br><b>COST:</b> [bloodcost] Blood" // Modify description to add cost.
if(warn_constant_cost)
@@ -46,7 +50,7 @@
// click.dm <--- Where we can take over mouse clicks
// spells.dm /add_ranged_ability() <--- How we take over the mouse click to use a power on a target.
/datum/action/bloodsucker/Trigger()
/datum/action/cooldown/bloodsucker/Trigger()
// Active? DEACTIVATE AND END!
if(active && CheckCanDeactivate(TRUE))
DeactivatePower()
@@ -56,7 +60,7 @@
PayCost()
if(amToggle)
active = !active
UpdateButtonIcon()
UpdateButtons()
if(!amToggle || !active)
StartCooldown() // Must come AFTER UpdateButton(), otherwise icon will revert.
ActivatePower() // NOTE: ActivatePower() freezes this power in place until it ends.
@@ -65,13 +69,13 @@
if(amSingleUse)
RemoveAfterUse()
/datum/action/bloodsucker/proc/CheckCanPayCost(display_error)
/datum/action/cooldown/bloodsucker/proc/CheckCanPayCost(display_error)
if(!owner || !owner.mind)
return FALSE
// Cooldown?
if(cooldownUntil > world.time)
if(next_use_time > world.time)
if(display_error)
to_chat(owner, "[src] is unavailable. Wait [(cooldownUntil - world.time) / 10] seconds.")
to_chat(owner, "[src] is unavailable. Wait [(next_use_time - world.time) / 10] seconds.")
return FALSE
// Have enough blood?
var/mob/living/L = owner
@@ -81,7 +85,7 @@
return FALSE
return TRUE
/datum/action/bloodsucker/proc/CheckCanUse(display_error) // These checks can be scanned every frame while a ranged power is on.
/datum/action/cooldown/bloodsucker/proc/CheckCanUse(display_error) // These checks can be scanned every frame while a ranged power is on.
if(!owner || !owner.mind)
return FALSE
// Torpor?
@@ -123,79 +127,43 @@
return FALSE
return TRUE
/datum/action/bloodsucker/proc/StartCooldown()
set waitfor = FALSE
// Alpha Out
button.color = rgb(128,0,0,128)
button.alpha = 100
// Calculate Cooldown (by power's level)
var/this_cooldown = (cooldown_static || amSingleUse) ? cooldown : max(cooldown / 2, cooldown - (cooldown / 16 * (level_current-1)))
// NOTE: With this formula, you'll hit half cooldown at level 8 for that power.
// Wait for cooldown
cooldownUntil = world.time + this_cooldown
spawn(this_cooldown)
// Alpha In
button.color = rgb(255,255,255,255)
button.alpha = 255
/datum/action/bloodsucker/proc/CheckCanDeactivate(display_error)
/datum/action/cooldown/bloodsucker/proc/CheckCanDeactivate(display_error)
return TRUE
/datum/action/bloodsucker/UpdateButtonIcon(force = FALSE)
/datum/action/cooldown/bloodsucker/UpdateButton(atom/movable/screen/movable/action_button/button, force = FALSE)
background_icon_state = active? background_icon_state_on : background_icon_state_off
..()//UpdateButtonIcon()
..()//UpdateButton()
/datum/action/bloodsucker/proc/PayCost()
/datum/action/cooldown/bloodsucker/proc/PayCost()
// owner for actions is the mob, not mind.
var/mob/living/L = owner
L.blood_volume -= bloodcost
/datum/action/bloodsucker/proc/ActivatePower()
/datum/action/cooldown/bloodsucker/proc/ActivatePower()
/datum/action/bloodsucker/proc/DeactivatePower(mob/living/user = owner, mob/living/target)
/datum/action/cooldown/bloodsucker/proc/DeactivatePower(mob/living/user = owner, mob/living/target)
active = FALSE
UpdateButtonIcon()
UpdateButtons()
StartCooldown()
/datum/action/bloodsucker/proc/ContinueActive(mob/living/user, mob/living/target) // Used by loops to make sure this power can stay active.
/datum/action/cooldown/bloodsucker/proc/ContinueActive(mob/living/user, mob/living/target) // Used by loops to make sure this power can stay active.
return active && user && (!warn_constant_cost || user.blood_volume > 0)
/datum/action/bloodsucker/proc/RemoveAfterUse()
/datum/action/cooldown/bloodsucker/proc/RemoveAfterUse()
// Un-Learn Me! (GO HOME
var/datum/antagonist/bloodsucker/bloodsuckerdatum = owner.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
if (istype(bloodsuckerdatum))
bloodsuckerdatum.powers -= src
Remove(owner)
/datum/action/bloodsucker/proc/Upgrade()
/datum/action/cooldown/bloodsucker/proc/Upgrade()
level_current ++
/////////////////////////////////// PASSIVE POWERS ///////////////////////////////////
// New Type: Passive (Always on, no button)
/datum/action/bloodsucker/passive
/datum/action/bloodsucker/passive/New()
// REMOVED: DO NOTHBING!
..()
// Don't Display Button! (it doesn't do anything anyhow)
button.screen_loc = DEFAULT_BLOODSPELLS
button.moved = DEFAULT_BLOODSPELLS
button.ordered = FALSE
/datum/action/bloodsucker/passive/Destroy()
if(owner)
Remove(owner)
target = null
return ..()
/////////////////////////////////// TARGETTED POWERS ///////////////////////////////////
/datum/action/bloodsucker/targeted
/datum/action/cooldown/bloodsucker/targeted
// NOTE: All Targeted spells are Toggles! We just don't bother checking here.
var/target_range = 99
var/message_Trigger = "Select a target."
@@ -204,7 +172,7 @@
var/power_in_use = FALSE // Is this power LOCKED due to being used?
/datum/action/bloodsucker/targeted/New(Target)
/datum/action/cooldown/bloodsucker/targeted/New(Target)
desc += "<br>\[<i>Targeted Power</i>\]" // Modify description to add notice that this is aimed.
..()
// Create Proc Holder for intercepting clicks
@@ -212,7 +180,7 @@
bs_proc_holder.linked_power = src
// Click power: Begin Aim
/datum/action/bloodsucker/targeted/Trigger()
/datum/action/cooldown/bloodsucker/targeted/Trigger()
if(active && CheckCanDeactivate(TRUE))
DeactivateRangedAbility()
DeactivatePower()
@@ -220,7 +188,7 @@
if(!CheckCanPayCost(TRUE) || !CheckCanUse(TRUE))
return
active = !active
UpdateButtonIcon()
UpdateButtons()
// Create & Link Targeting Proc
var/mob/living/L = owner
if(L.ranged_ability)
@@ -230,7 +198,7 @@
if(message_Trigger != "")
to_chat(owner, "<span class='announce'>[message_Trigger]</span>")
/datum/action/bloodsucker/targeted/CheckCanUse(display_error)
/datum/action/cooldown/bloodsucker/targeted/CheckCanUse(display_error)
. = ..()
if(!.)
return
@@ -238,21 +206,21 @@
return FALSE // doesn't let you remove powers if you're not there. So, let's just cancel the power entirely.
return TRUE
/datum/action/bloodsucker/targeted/DeactivatePower(mob/living/user = owner, mob/living/target)
/datum/action/cooldown/bloodsucker/targeted/DeactivatePower(mob/living/user = owner, mob/living/target)
// Don't run ..(), we don't want to engage the cooldown until we USE this power!
active = FALSE
UpdateButtonIcon()
UpdateButtons()
/datum/action/bloodsucker/targeted/proc/DeactivateRangedAbility()
/datum/action/cooldown/bloodsucker/targeted/proc/DeactivateRangedAbility()
// Only Turned off when CLICK is disabled...aka, when you successfully clicked (or
bs_proc_holder.remove_ranged_ability()
// Check if target is VALID (wall, turf, or character?)
/datum/action/bloodsucker/targeted/proc/CheckValidTarget(atom/A)
/datum/action/cooldown/bloodsucker/targeted/proc/CheckValidTarget(atom/A)
return FALSE // FALSE targets nothing.
// Check if valid target meets conditions
/datum/action/bloodsucker/targeted/proc/CheckCanTarget(atom/A, display_error)
/datum/action/cooldown/bloodsucker/targeted/proc/CheckCanTarget(atom/A, display_error)
// Out of Range
if(!(A in view(target_range, owner)))
if(display_error && target_range > 1) // Only warn for range if it's greater than 1. Brawn doesn't need to announce itself.
@@ -261,7 +229,7 @@
return istype(A)
// Click Target
/datum/action/bloodsucker/targeted/proc/ClickWithPower(atom/A)
/datum/action/cooldown/bloodsucker/targeted/proc/ClickWithPower(atom/A)
// CANCEL RANGED TARGET check
if(power_in_use || !CheckValidTarget(A))
return FALSE
@@ -276,21 +244,21 @@
power_in_use = FALSE
return TRUE
/datum/action/bloodsucker/targeted/proc/FireTargetedPower(atom/A)
/datum/action/cooldown/bloodsucker/targeted/proc/FireTargetedPower(atom/A)
// Like ActivatePower, but specific to Targeted (and takes an atom input). We don't use ActivatePower for targeted.
/datum/action/bloodsucker/targeted/proc/PowerActivatedSuccessfully()
/datum/action/cooldown/bloodsucker/targeted/proc/PowerActivatedSuccessfully()
// The power went off! We now pay the cost of the power.
PayCost()
DeactivateRangedAbility()
DeactivatePower()
StartCooldown() // Do AFTER UpdateIcon() inside of DeactivatePower. Otherwise icon just gets wiped.
/datum/action/bloodsucker/targeted/ContinueActive(mob/living/user, mob/living/target) // Used by loops to make sure this power can stay active.
/datum/action/cooldown/bloodsucker/targeted/ContinueActive(mob/living/user, mob/living/target) // Used by loops to make sure this power can stay active.
return ..()
// Target Proc Holder
/obj/effect/proc_holder/bloodsucker
var/datum/action/bloodsucker/targeted/linked_power
var/datum/action/cooldown/bloodsucker/targeted/linked_power
/obj/effect/proc_holder/bloodsucker/remove_ranged_ability(msg)
..()
@@ -55,8 +55,8 @@
bloodsuckerdatum.warn_sun_locker = FALSE
bloodsuckerdatum.warn_sun_burn = FALSE
// Remove Dawn Powers
for(var/datum/action/bloodsucker/P in bloodsuckerdatum.powers)
if(istype(P, /datum/action/bloodsucker/gohome))
for(var/datum/action/cooldown/bloodsucker/P in bloodsuckerdatum.powers)
if(istype(P, /datum/action/cooldown/bloodsucker/gohome))
bloodsuckerdatum.powers -= P
P.Remove(M.current)
nighttime_duration += 100 //Each day makes the night a minute longer.
@@ -149,5 +149,5 @@
if(!istype(M) || !istype(M.current))
continue
var/datum/antagonist/bloodsucker/bloodsuckerdatum = M.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
if(istype(bloodsuckerdatum) && bloodsuckerdatum.lair && !(locate(/datum/action/bloodsucker/gohome) in bloodsuckerdatum.powers))
bloodsuckerdatum.BuyPower(new /datum/action/bloodsucker/gohome)
if(istype(bloodsuckerdatum) && bloodsuckerdatum.lair && !(locate(/datum/action/cooldown/bloodsucker/gohome) in bloodsuckerdatum.powers))
bloodsuckerdatum.BuyPower(new /datum/action/cooldown/bloodsucker/gohome)
@@ -14,7 +14,7 @@
dat += "<HR>"
// Step One: Decide powers you CAN buy.
for(var/pickedpower in typesof(/datum/action/bloodsucker))
for(var/pickedpower in typesof(/datum/action/cooldown/bloodsucker))
var/obj/effect/proc_holder/spell/bloodsucker/power = pickedpower
// NAME
dat += "<A href='byond://?src=[REF(src)];[module.mod_pick_name]=1'>[power.name]</A>"
@@ -168,7 +168,7 @@
return fullname
/datum/antagonist/bloodsucker/proc/BuyPower(datum/action/bloodsucker/power)//(obj/effect/proc_holder/spell/power)
/datum/antagonist/bloodsucker/proc/BuyPower(datum/action/cooldown/bloodsucker/power)//(obj/effect/proc_holder/spell/power)
powers += power
power.Grant(owner.current)// owner.AddSpell(power)
@@ -177,9 +177,9 @@
add_hud()
update_hud(TRUE) // Set blood value, current rank
// Powers
BuyPower(new /datum/action/bloodsucker/feed)
BuyPower(new /datum/action/bloodsucker/masquerade)
BuyPower(new /datum/action/bloodsucker/veil)
BuyPower(new /datum/action/cooldown/bloodsucker/feed)
BuyPower(new /datum/action/cooldown/bloodsucker/masquerade)
BuyPower(new /datum/action/cooldown/bloodsucker/veil)
// Traits
for(var/T in defaultTraits)
ADD_TRAIT(owner.current, T, BLOODSUCKER_TRAIT)
@@ -221,7 +221,7 @@
remove_hud()
// Powers
while(powers.len)
var/datum/action/bloodsucker/power = pick(powers)
var/datum/action/cooldown/bloodsucker/power = pick(powers)
powers -= power
power.Remove(owner.current)
// owner.RemoveSpell(power)
@@ -267,7 +267,7 @@
to_chat(owner, "<span class='announce'>Bloodsucker Tip: If you cannot find or steal a coffin to use, you can build one from wooden planks.</span><br>")
/datum/antagonist/bloodsucker/proc/LevelUpPowers()
for(var/datum/action/bloodsucker/power in powers)
for(var/datum/action/cooldown/bloodsucker/power in powers)
power.level_current ++
/datum/antagonist/bloodsucker/proc/SpendRank()
@@ -281,8 +281,8 @@
//TODO: Make this into a radial, or perhaps a tgui next UI
// Purchase Power Prompt
var/list/options = list()
for(var/pickedpower in typesof(/datum/action/bloodsucker))
var/datum/action/bloodsucker/power = pickedpower
for(var/pickedpower in typesof(/datum/action/cooldown/bloodsucker))
var/datum/action/cooldown/bloodsucker/power = pickedpower
// If I don't own it, and I'm allowed to buy it.
if(!(locate(power) in powers) && initial(power.bloodsucker_can_buy))
options[initial(power.name)] = power // TESTING: After working with TGUI, it seems you can use initial() to view the variables inside a path?
@@ -303,7 +303,7 @@
to_chat(owner.current, "<span class='warning'>You dont have enough blood to thicken your blood, you need [level_bloodcost - L.blood_volume] units more!</span>")
return
// Buy New Powers
var/datum/action/bloodsucker/P = options[choice]
var/datum/action/cooldown/bloodsucker/P = options[choice]
AddBloodVolume(-level_bloodcost)
BuyPower(new P)
to_chat(owner.current, "<span class='notice'>You have used [level_bloodcost] units of blood and learned [initial(P.name)]!</span>")
@@ -725,7 +725,7 @@
/atom/movable/screen/bloodsucker/blood_counter/update_counter(value, valuecolor)
..()
maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='[valuecolor]'>[round(value,1)]</font></div>"
maptext = MAPTEXT("<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='[valuecolor]'>[round(value,1)]</font></div>")
/atom/movable/screen/bloodsucker/rank_counter
name = "Bloodsucker Rank"
@@ -735,7 +735,7 @@
/atom/movable/screen/bloodsucker/rank_counter/update_counter(value, valuecolor)
..()
maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='[valuecolor]'>[round(value,1)]</font></div>"
maptext = MAPTEXT("<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='[valuecolor]'>[round(value,1)]</font></div>")
/atom/movable/screen/bloodsucker/sunlight_counter
icon = 'icons/mob/actions/bloodsucker.dmi'
@@ -763,7 +763,7 @@
/atom/movable/screen/bloodsucker/sunlight_counter/update_counter(value, valuecolor)
..()
maptext = "<div align='center' valign='bottom' style='position:relative; top:0px; left:6px'><font color='[valuecolor]'>[value]</font></div>"
maptext = MAPTEXT("<div align='center' valign='bottom' style='position:relative; top:0px; left:6px'><font color='[valuecolor]'>[value]</font></div>")
/datum/antagonist/bloodsucker/proc/count_vassals(datum/mind/master)
var/datum/antagonist/bloodsucker/B = master.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
@@ -26,7 +26,7 @@
//owner.current.apply_status_effect(/datum/status_effect/agent_pinpointer/hunter_edition)
// Give Hunter Power
var/datum/action/P = new /datum/action/bloodsucker/trackvamp
var/datum/action/P = new /datum/action/cooldown/bloodsucker/trackvamp
P.Grant(owner.current)
// Give Hunter Martial Arts
@@ -69,7 +69,7 @@
// Take Hunter Power
if (owner.current)
for (var/datum/action/bloodsucker/P in owner.current.actions)
for (var/datum/action/cooldown/bloodsucker/P in owner.current.actions)
P.Remove(owner.current)
// Take Hunter Martial Arts
@@ -166,7 +166,7 @@
/*
/datum/action/bloodsucker/trackvamp/
/datum/action/cooldown/bloodsucker/trackvamp/
name = "Track Monster"//"Cellular Emporium"
desc = "Take a moment to look for clues of any nearby monsters.<br>These creatures are slippery, and often look like the crew."
button_icon = 'icons/mob/actions/bloodsucker.dmi' //This is the file for the BACKGROUND icon
@@ -177,7 +177,7 @@
cooldown = 300 // 10 ticks, 1 second.
bloodcost = 0
/datum/action/bloodsucker/trackvamp/ActivatePower()
/datum/action/cooldown/bloodsucker/trackvamp/ActivatePower()
var/mob/living/user = owner
to_chat(user, "<span class='notice'>You look around, scanning your environment and discerning signs of any filthy, wretched affronts to the natural order.</span>")
@@ -192,7 +192,7 @@
// NOTE: DON'T DEACTIVATE!
//DeactivatePower()
/datum/action/bloodsucker/trackvamp/proc/display_proximity()
/datum/action/cooldown/bloodsucker/trackvamp/proc/display_proximity()
// Pick target
var/turf/my_loc = get_turf(owner)
//var/list/mob/living/carbon/vamps = list()
@@ -38,7 +38,7 @@
// Master Pinpointer
owner.current.apply_status_effect(/datum/status_effect/agent_pinpointer/vassal_edition)
// Powers
var/datum/action/bloodsucker/vassal/recuperate/new_Recuperate = new ()
var/datum/action/cooldown/bloodsucker/vassal/recuperate/new_Recuperate = new ()
new_Recuperate.Grant(owner.current)
powers += new_Recuperate
// Give Vassal Objective
@@ -33,7 +33,7 @@
/obj/item/organ/heart/vampheart/Restart()
beating = 0 // DONT run ..(). We don't want to start beating again.
return 0
return FALSE
/obj/item/organ/heart/vampheart/Stop()
fakingit = 0
@@ -122,7 +122,7 @@
update_icon()
//to_chat(user, "<span class='notice'>You flip a secret latch and unlock [src].</span>") // Don't bother. We know it's unlocked.
locked = FALSE
return 1
return TRUE
else
playsound(get_turf(src), 'sound/machines/door_locked.ogg', 20, 1)
to_chat(user, "<span class='notice'>[src] is locked tight from the inside.</span>")
@@ -1,11 +1,11 @@
/datum/action/bloodsucker/targeted/brawn
/datum/action/cooldown/bloodsucker/targeted/brawn
name = "Brawn"
desc = "Snap restraints with ease, or deal terrible damage with your bare hands."
button_icon_state = "power_strength"
bloodcost = 10
cooldown = 90
cooldown_time = 90
target_range = 1
power_activates_immediately = TRUE
message_Trigger = ""//"Whom will you subvert to your will?"
@@ -16,7 +16,7 @@
var/upgrade_canLocker = FALSE
var/upgrade_canDoor = FALSE
/datum/action/bloodsucker/targeted/brawn/CheckCanUse(display_error)
/datum/action/cooldown/bloodsucker/targeted/brawn/CheckCanUse(display_error)
. = ..()
if(!.)
return
@@ -38,10 +38,10 @@
// NOTE: We use . = FALSE so that we can break cuffs AND throw off our attacker in one use!
//return TRUE
/datum/action/bloodsucker/targeted/brawn/CheckValidTarget(atom/A)
/datum/action/cooldown/bloodsucker/targeted/brawn/CheckValidTarget(atom/A)
return isliving(A) || istype(A, /obj/machinery/door)
/datum/action/bloodsucker/targeted/brawn/CheckCanTarget(atom/A, display_error)
/datum/action/cooldown/bloodsucker/targeted/brawn/CheckCanTarget(atom/A, display_error)
// DEFAULT CHECKS (Distance)
if(!..()) // Disable range notice for Brawn.
return FALSE
@@ -59,7 +59,7 @@
return TRUE
return ..() // yes, FALSE! You failed if you got here! BAD TARGET
/datum/action/bloodsucker/targeted/brawn/FireTargetedPower(atom/A)
/datum/action/cooldown/bloodsucker/targeted/brawn/FireTargetedPower(atom/A)
// set waitfor = FALSE <---- DONT DO THIS!We WANT this power to hold up ClickWithPower(), so that we can unlock the power when it's done.
var/mob/living/carbon/target = A
var/mob/living/user = owner
@@ -97,7 +97,7 @@
D.open(2) // open(2) is like a crowbar or jaws of life.
// Target Type: Closet
/datum/action/bloodsucker/targeted/brawn/proc/CheckBreakRestraints()
/datum/action/cooldown/bloodsucker/targeted/brawn/proc/CheckBreakRestraints()
if(!iscarbon(owner)) // || !owner.restrained()
return FALSE
// (NOTE: Just like biodegrade.dm, we only remove one thing per use //
@@ -131,7 +131,7 @@
return TRUE
return FALSE
/datum/action/bloodsucker/targeted/brawn/proc/CheckEscapePuller()
/datum/action/cooldown/bloodsucker/targeted/brawn/proc/CheckEscapePuller()
if(!owner.pulledby)// || owner.pulledby.grab_state <= GRAB_PASSIVE)
return FALSE
var/mob/M = owner.pulledby
@@ -153,7 +153,7 @@
owner.pulledby = null // It's already done, but JUST IN CASE.
return TRUE
/* Doesnt work
/datum/action/bloodsucker/targeted/brawn/proc/CheckBreakLocker()
/datum/action/cooldown/bloodsucker/targeted/brawn/proc/CheckBreakLocker()
if(!istype(owner.loc, /obj/structure/closet))
return FALSE
playsound(get_turf(owner), 'sound/machines/airlock_alien_prying.ogg', 40, 1, -1)
@@ -1,11 +1,11 @@
/datum/action/bloodsucker/cloak
/datum/action/cooldown/bloodsucker/cloak
name = "Cloak of Darkness"
desc = "Blend into the shadows and become invisible to the untrained eye. Movement is slowed in brightly lit areas, and you cannot dissapear while mortals watch you."
button_icon_state = "power_cloak"
bloodcost = 5
cooldown = 50
cooldown_time = 50
bloodsucker_can_buy = TRUE
amToggle = TRUE
warn_constant_cost = TRUE
@@ -14,7 +14,7 @@
var/walk_threshold = 0.4 // arbitrary number, to be changed. edit in last commit: this is fine after testing on box station for a bit
var/lum
/datum/action/bloodsucker/cloak/CheckCanUse(display_error)
/datum/action/cooldown/bloodsucker/cloak/CheckCanUse(display_error)
. = ..()
if(!.)
return
@@ -24,7 +24,7 @@
return FALSE
return TRUE
/datum/action/bloodsucker/cloak/ActivatePower()
/datum/action/cooldown/bloodsucker/cloak/ActivatePower()
var/datum/antagonist/bloodsucker/bloodsuckerdatum = owner.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
var/mob/living/user = owner
@@ -52,7 +52,7 @@
sleep(5) // Check every few ticks
/datum/action/bloodsucker/cloak/ContinueActive(mob/living/user, mob/living/target)
/datum/action/cooldown/bloodsucker/cloak/ContinueActive(mob/living/user, mob/living/target)
if (!..())
return FALSE
if(user.stat == !CONSCIOUS) // Must be CONSCIOUS
@@ -60,7 +60,7 @@
return FALSE
return TRUE
/datum/action/bloodsucker/cloak/DeactivatePower(mob/living/user = owner, mob/living/target)
/datum/action/cooldown/bloodsucker/cloak/DeactivatePower(mob/living/user = owner, mob/living/target)
..()
REMOVE_TRAIT(user, TRAIT_NORUNNING, "cloak of darkness")
user.alpha = 255
@@ -1,12 +1,12 @@
/datum/action/bloodsucker/feed
/datum/action/cooldown/bloodsucker/feed
name = "Feed"
desc = "Draw the heartsblood of living victims in your grasp.<br><b>None/Passive:</b> Feed silently and unnoticed by your victim.<br><b>Aggressive: </b>Subdue your target quickly."
button_icon_state = "power_feed"
bloodcost = 0
cooldown = 30
cooldown_time = 30
amToggle = TRUE
bloodsucker_can_buy = TRUE
can_be_staked = TRUE
@@ -16,7 +16,7 @@
var/mob/living/feed_target // So we can validate more than just the guy we're grappling.
var/target_grappled = FALSE // If you started grappled, then ending it will end your Feed.
/datum/action/bloodsucker/feed/CheckCanUse(display_error)
/datum/action/cooldown/bloodsucker/feed/CheckCanUse(display_error)
. = ..()
if(!.)
return
@@ -33,7 +33,7 @@
// DONE!
return TRUE
/datum/action/bloodsucker/feed/proc/ValidateTarget(mob/living/target, display_error) // Called twice: validating a subtle victim, or validating your grapple victim.
/datum/action/cooldown/bloodsucker/feed/proc/ValidateTarget(mob/living/target, display_error) // Called twice: validating a subtle victim, or validating your grapple victim.
// Bloodsuckers + Animals MUST be grabbed aggressively!
if(!owner.pulling || target == owner.pulling && owner.grab_state < GRAB_AGGRESSIVE)
// NOTE: It's OKAY that we are checking if(!target) below, AFTER animals here. We want passive check vs animal to warn you first, THEN the standard warning.
@@ -76,7 +76,7 @@
return TRUE
// If I'm not grabbing someone, find me someone nearby.
/datum/action/bloodsucker/feed/proc/FindMyTarget(display_error)
/datum/action/cooldown/bloodsucker/feed/proc/FindMyTarget(display_error)
// Default
feed_target = null
target_grappled = FALSE
@@ -132,7 +132,7 @@
feed_target = pick(targets_valid)//targets[1]
return TRUE
/datum/action/bloodsucker/feed/ActivatePower()
/datum/action/cooldown/bloodsucker/feed/ActivatePower()
// set waitfor = FALSE <---- DONT DO THIS!We WANT this power to hold up Activate(), so Deactivate() can happen after.
var/mob/living/target = feed_target // Stored during CheckCanUse(). Can be a grabbed OR adjecent character.
var/mob/living/user = owner
@@ -302,16 +302,16 @@
CheckKilledTarget(user,target)
/datum/action/bloodsucker/feed/proc/CheckKilledTarget(mob/living/user, mob/living/target)
/datum/action/cooldown/bloodsucker/feed/proc/CheckKilledTarget(mob/living/user, mob/living/target)
// Bad Bloodsucker. You shouldn't do that.
if(target && target.stat >= DEAD && ishuman(target))
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "drankkilled", /datum/mood_event/drankkilled) // BAD // in bloodsucker_life.dm
/datum/action/bloodsucker/feed/ContinueActive(mob/living/user, mob/living/target)
/datum/action/cooldown/bloodsucker/feed/ContinueActive(mob/living/user, mob/living/target)
return ..() && target && (!target_grappled || user.pulling == target) && blood_sucking_checks(target, TRUE, TRUE) // Active, and still antag,
// NOTE: We only care about pulling if target started off that way. Mostly only important for Aggressive feed.
/datum/action/bloodsucker/feed/proc/ApplyVictimEffects(mob/living/target)
/datum/action/cooldown/bloodsucker/feed/proc/ApplyVictimEffects(mob/living/target)
// Bloodsuckers not affected by "the Kiss" of another vampire
if(!target.mind || !target.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
target.Unconscious(50,0)
@@ -320,7 +320,7 @@
if(ishuman(target))
target.adjustStaminaLoss(5, forced = TRUE)// Base Stamina Damage
/datum/action/bloodsucker/feed/DeactivatePower(mob/living/user = owner, mob/living/target)
/datum/action/cooldown/bloodsucker/feed/DeactivatePower(mob/living/user = owner, mob/living/target)
..() // activate = FALSE
var/datum/antagonist/bloodsucker/bloodsuckerdatum = user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
// No longer Feeding
@@ -2,12 +2,12 @@
/datum/action/bloodsucker/fortitude
/datum/action/cooldown/bloodsucker/fortitude
name = "Fortitude"
desc = "Withstand egregious physical wounds and walk away from attacks that would stun, pierce, and dismember lesser beings. You cannot run while active."
button_icon_state = "power_fortitude"
bloodcost = 30
cooldown = 80
cooldown_time = 80
bloodsucker_can_buy = TRUE
amToggle = TRUE
warn_constant_cost = TRUE
@@ -15,7 +15,7 @@
var/fortitude_resist // So we can raise and lower your brute resist based on what your level_current WAS.
/datum/action/bloodsucker/fortitude/ActivatePower()
/datum/action/cooldown/bloodsucker/fortitude/ActivatePower()
var/datum/antagonist/bloodsucker/B = owner.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
var/mob/living/user = owner
to_chat(user, "<span class='notice'>Your flesh, skin, and muscles become as steel.</span>")
@@ -47,8 +47,8 @@
B.AddBloodVolume(-0.5)
sleep(20) // Check every few ticks that we haven't disabled this power
// Return to Running (if you were before)
/datum/action/bloodsucker/fortitude/DeactivatePower(mob/living/user = owner, mob/living/target)
/datum/action/cooldown/bloodsucker/fortitude/DeactivatePower(mob/living/user = owner, mob/living/target)
..()
// Restore Traits & Effects
REMOVE_TRAIT(user, TRAIT_PIERCEIMMUNE, "fortitude")
@@ -1,6 +1,6 @@
/datum/action/bloodsucker/gohome
/datum/action/cooldown/bloodsucker/gohome
name = "Vanishing Act"
desc = "As dawn aproaches, disperse into mist and return directly to your Lair.<br><b>WARNING:</b> You will drop <b>ALL</b> of your possessions if observed by mortals."
button_icon_state = "power_gohome"
@@ -8,7 +8,7 @@
background_icon_state_off = "vamp_power_off_oneshot"
bloodcost = 100
cooldown = 99999 // It'll never come back.
cooldown_time = 99999 // It'll never come back.
amToggle = FALSE
amSingleUse = TRUE
@@ -18,7 +18,7 @@
can_be_immobilized = TRUE
must_be_concious = FALSE
/datum/action/bloodsucker/gohome/CheckCanUse(display_error)
/datum/action/cooldown/bloodsucker/gohome/CheckCanUse(display_error)
. = ..()
if(!.)
return
@@ -30,12 +30,12 @@
return FALSE
return TRUE
/datum/action/bloodsucker/gohome/proc/flicker_lights(var/flicker_range, var/beat_volume)
/datum/action/cooldown/bloodsucker/gohome/proc/flicker_lights(var/flicker_range, var/beat_volume)
for(var/obj/machinery/light/L in view(flicker_range, get_turf(owner)))
playsound(get_turf(owner), 'sound/effects/singlebeat.ogg', beat_volume, 1)
/datum/action/bloodsucker/gohome/ActivatePower()
/datum/action/cooldown/bloodsucker/gohome/ActivatePower()
var/mob/living/carbon/user = owner
var/datum/antagonist/bloodsucker/bloodsuckerdatum = owner.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
// IMPORTANT: Check for lair at every step! It might get destroyed.
@@ -3,12 +3,12 @@
// Level 2: Dodge Bullets
// Level 3: Stun People Passed
/datum/action/bloodsucker/targeted/haste
/datum/action/cooldown/bloodsucker/targeted/haste
name = "Immortal Haste"
desc = "Dash somewhere with supernatural speed. Those nearby may be knocked away, stunned, or left empty-handed."
button_icon_state = "power_speed"
bloodcost = 6
cooldown = 120
cooldown_time = 120
target_range = 15
power_activates_immediately = TRUE
message_Trigger = ""//"Whom will you subvert to your will?"
@@ -18,7 +18,7 @@
/// If set, uses this speed in deciseconds instead of world.tick_lag
var/speed_override
/datum/action/bloodsucker/targeted/haste/CheckCanUse(display_error)
/datum/action/cooldown/bloodsucker/targeted/haste/CheckCanUse(display_error)
. = ..()
if(!.)
return
@@ -33,10 +33,10 @@
return FALSE
return TRUE
/datum/action/bloodsucker/targeted/haste/CheckValidTarget(atom/A)
/datum/action/cooldown/bloodsucker/targeted/haste/CheckValidTarget(atom/A)
return isturf(A) || A.loc != owner.loc // Anything will do, if it's not me or my square
/datum/action/bloodsucker/targeted/haste/CheckCanTarget(atom/A, display_error)
/datum/action/cooldown/bloodsucker/targeted/haste/CheckCanTarget(atom/A, display_error)
// DEFAULT CHECKS (Distance)
if (!..())
return FALSE
@@ -45,7 +45,7 @@
// return FALSE
return TRUE
/datum/action/bloodsucker/targeted/haste/FireTargetedPower(atom/A)
/datum/action/cooldown/bloodsucker/targeted/haste/FireTargetedPower(atom/A)
// This is a non-async proc to make sure the power is "locked" until this finishes.
hit = list()
RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
@@ -78,11 +78,11 @@
hit = null
user.update_mobility()
/datum/action/bloodsucker/targeted/haste/DeactivatePower(mob/living/user = owner, mob/living/target)
/datum/action/cooldown/bloodsucker/targeted/haste/DeactivatePower(mob/living/user = owner, mob/living/target)
..() // activate = FALSE
user.update_mobility()
/datum/action/bloodsucker/targeted/haste/proc/on_move()
/datum/action/cooldown/bloodsucker/targeted/haste/proc/on_move()
for(var/mob/living/L in dview(1, get_turf(owner)))
if(!hit[L] && (L != owner))
hit[L] = TRUE
@@ -1,25 +1,21 @@
/datum/action/bloodsucker/lunge
/datum/action/cooldown/bloodsucker/lunge
name = "Predatory Lunge"
desc = "Prepare the strenght to grapple your prey."
button_icon_state = "power_lunge"
bloodcost = 10
cooldown = 30
cooldown_time = 30
bloodsucker_can_buy = TRUE
warn_constant_cost = TRUE
amToggle = TRUE
var/leap_skill_mod = 5
/datum/action/bloodsucker/lunge/New()
. = ..()
/datum/action/bloodsucker/lunge/Destroy()
/datum/action/cooldown/bloodsucker/lunge/Destroy()
. = ..()
UnregisterSignal(owner, COMSIG_CARBON_TACKLED)
/datum/action/bloodsucker/lunge/ActivatePower()
/datum/action/cooldown/bloodsucker/lunge/ActivatePower()
var/mob/living/carbon/user = owner
var/datum/antagonist/bloodsucker/B = user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
var/datum/component/tackler/T = user.LoadComponent(/datum/component/tackler)
@@ -37,10 +33,10 @@
sleep(5)
//Without this, the leap component would get removed too early, causing the normal crash into effects.
/datum/action/bloodsucker/lunge/proc/DelayedDeactivatePower()
/datum/action/cooldown/bloodsucker/lunge/proc/DelayedDeactivatePower()
addtimer(CALLBACK(src, PROC_REF(DeactivatePower)), 1 SECONDS, TIMER_UNIQUE)
/datum/action/bloodsucker/lunge/DeactivatePower(mob/living/user = owner)
/datum/action/cooldown/bloodsucker/lunge/DeactivatePower(mob/living/user = owner)
. = ..()
qdel(user.GetComponent(/datum/component/tackler))
UnregisterSignal(user, COMSIG_CARBON_TACKLED)
@@ -16,12 +16,12 @@
// -
/datum/action/bloodsucker/masquerade
/datum/action/cooldown/bloodsucker/masquerade
name = "Masquerade"
desc = "Feign the vital signs of a mortal, and escape both casual and medical notice as the monster you truly are."
button_icon_state = "power_human"
bloodcost = 10
cooldown = 50
cooldown_time = 50
amToggle = TRUE
bloodsucker_can_buy = TRUE
warn_constant_cost = TRUE
@@ -31,7 +31,7 @@
// NOTE: Firing off vulgar powers disables your Masquerade!
/*/datum/action/bloodsucker/masquerade/CheckCanUse(display_error)
/*/datum/action/cooldown/bloodsucker/masquerade/CheckCanUse(display_error)
if(!..(display_error))// DEFAULT CHECKS
return FALSE
// DONE!
@@ -39,7 +39,7 @@
*/
/datum/action/bloodsucker/masquerade/ActivatePower()
/datum/action/cooldown/bloodsucker/masquerade/ActivatePower()
var/mob/living/user = owner
var/datum/antagonist/bloodsucker/bloodsuckerdatum = user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
@@ -78,14 +78,14 @@
sleep(20) // Check every few ticks that we haven't disabled this power
/datum/action/bloodsucker/masquerade/ContinueActive(mob/living/user)
/datum/action/cooldown/bloodsucker/masquerade/ContinueActive(mob/living/user)
// Disable if unable to use power anymore.
//if (user.stat == DEAD || user.blood_volume <= 0) // not conscious or soft critor uncon, just dead
// return FALSE
return ..() // Active, and still Antag
/datum/action/bloodsucker/masquerade/DeactivatePower(mob/living/user = owner, mob/living/target)
/datum/action/cooldown/bloodsucker/masquerade/DeactivatePower(mob/living/user = owner, mob/living/target)
..() // activate = FALSE
var/datum/antagonist/bloodsucker/bloodsuckerdatum = user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
@@ -5,12 +5,12 @@
// FOLLOW: Target follows you, spouting random phrases from their history (or maybe Polly's or NPC's vocab?)
// ATTACK: Target finds a nearby non-Bloodsucker victim to attack.
/datum/action/bloodsucker/targeted/mesmerize
/datum/action/cooldown/bloodsucker/targeted/mesmerize
name = "Mesmerize"
desc = "Dominate the mind of a mortal who can see your eyes."
button_icon_state = "power_mez"
bloodcost = 30
cooldown = 300
cooldown_time = 300
target_range = 2
power_activates_immediately = TRUE
message_Trigger = "Whom will you subvert to your will?"
@@ -18,7 +18,7 @@
bloodsucker_can_buy = TRUE
var/success
/datum/action/bloodsucker/targeted/mesmerize/CheckCanUse(display_error)
/datum/action/cooldown/bloodsucker/targeted/mesmerize/CheckCanUse(display_error)
. = ..()
if(!.)
return
@@ -34,10 +34,10 @@
return FALSE
return TRUE
/datum/action/bloodsucker/targeted/mesmerize/CheckValidTarget(atom/A)
/datum/action/cooldown/bloodsucker/targeted/mesmerize/CheckValidTarget(atom/A)
return iscarbon(A)
/datum/action/bloodsucker/targeted/mesmerize/CheckCanTarget(atom/A,display_error)
/datum/action/cooldown/bloodsucker/targeted/mesmerize/CheckCanTarget(atom/A,display_error)
// Check: Self
if(A == owner)
return FALSE
@@ -88,7 +88,7 @@
return FALSE
return TRUE
/datum/action/bloodsucker/targeted/mesmerize/proc/ContinueTarget(atom/A)
/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/ContinueTarget(atom/A)
var/mob/living/carbon/target = A
var/mob/living/L = owner
@@ -103,7 +103,7 @@
to_chat(L, "<span class='warning'>[target] has escaped your gaze!</span>")
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
/datum/action/bloodsucker/targeted/mesmerize/FireTargetedPower(atom/A)
/datum/action/cooldown/bloodsucker/targeted/mesmerize/FireTargetedPower(atom/A)
// set waitfor = FALSE <---- DONT DO THIS!We WANT this power to hold up ClickWithPower(), so that we can unlock the power when it's done.
var/mob/living/carbon/target = A
var/mob/living/L = owner
@@ -118,7 +118,7 @@
// 5 second windup
addtimer(CALLBACK(src, PROC_REF(apply_effects), L, target, power_time), 6 SECONDS)
/datum/action/bloodsucker/targeted/mesmerize/proc/apply_effects(aggressor, victim, power_time)
/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/apply_effects(aggressor, victim, power_time)
var/mob/living/carbon/target = victim
var/mob/living/L = aggressor
if(!success)
@@ -135,5 +135,5 @@
to_chat(L, "<span class='warning'>[target] has snapped out of their trance.</span>")
/datum/action/bloodsucker/targeted/mesmerize/ContinueActive(mob/living/user, mob/living/target)
/datum/action/cooldown/bloodsucker/targeted/mesmerize/ContinueActive(mob/living/user, mob/living/target)
return ..() && CheckCanUse() && CheckCanTarget(target)
@@ -1,12 +1,12 @@
/datum/action/bloodsucker/vassal/recuperate
/datum/action/cooldown/bloodsucker/vassal/recuperate
name = "Sanguine Recuperation"
desc = "Slowly heal brute damage while active. This process is exhausting, and requires some of your tainted blood."
button_icon_state = "power_recup"
amToggle = TRUE
bloodcost = 5
cooldown = 100
cooldown_time = 100
/datum/action/bloodsucker/vassal/recuperate/CheckCanUse(display_error)
/datum/action/cooldown/bloodsucker/vassal/recuperate/CheckCanUse(display_error)
. = ..()
if(!.)
return
@@ -14,7 +14,7 @@
return FALSE
return TRUE
/datum/action/bloodsucker/vassal/recuperate/ActivatePower()
/datum/action/cooldown/bloodsucker/vassal/recuperate/ActivatePower()
to_chat(owner, "<span class='notice'>Your muscles clench and your skin crawls as your master's immortal blood knits your wounds and gives you stamina.</span>")
var/mob/living/carbon/C = owner
var/mob/living/carbon/human/H
@@ -35,5 +35,5 @@
// DONE!
//DeactivatePower(owner)
/datum/action/bloodsucker/vassal/recuperate/ContinueActive(mob/living/user, mob/living/target)
/datum/action/cooldown/bloodsucker/vassal/recuperate/ContinueActive(mob/living/user, mob/living/target)
return ..() && user.stat <= DEAD && user.blood_volume > 500
@@ -1,12 +1,12 @@
/datum/action/bloodsucker/targeted/trespass
/datum/action/cooldown/bloodsucker/targeted/trespass
name = "Trespass"
desc = "Become mist and advance two tiles in one direction, ignoring all obstacles except for walls. Useful for skipping past doors and barricades."
button_icon_state = "power_tres"
bloodcost = 10
cooldown = 80
cooldown_time = 80
amToggle = FALSE
//target_range = 2
@@ -16,7 +16,7 @@
var/turf/target_turf // We need to decide where we're going based on where we clicked. It's not actually the tile we clicked.
/datum/action/bloodsucker/targeted/trespass/CheckCanUse(display_error)
/datum/action/cooldown/bloodsucker/targeted/trespass/CheckCanUse(display_error)
. = ..()
if(!.)
return
@@ -26,7 +26,7 @@
return TRUE
/datum/action/bloodsucker/targeted/trespass/CheckValidTarget(atom/A)
/datum/action/cooldown/bloodsucker/targeted/trespass/CheckValidTarget(atom/A)
// Can't target my tile
if(A == get_turf(owner) || get_turf(A) == get_turf(owner))
return FALSE
@@ -34,7 +34,7 @@
return TRUE // All we care about is destination. Anything you click is fine.
/datum/action/bloodsucker/targeted/trespass/CheckCanTarget(atom/A, display_error)
/datum/action/cooldown/bloodsucker/targeted/trespass/CheckCanTarget(atom/A, display_error)
// NOTE: Do NOT use ..()! We don't want to check distance or anything.
// Get clicked tile
@@ -60,7 +60,7 @@
return TRUE
/datum/action/bloodsucker/targeted/trespass/FireTargetedPower(atom/A)
/datum/action/cooldown/bloodsucker/targeted/trespass/FireTargetedPower(atom/A)
// set waitfor = FALSE <---- DONT DO THIS!We WANT this power to hold up ClickWithPower(), so that we can unlock the power when it's done.
// Find target turf, at or below Atom
@@ -87,7 +87,7 @@
user.invisibility = INVISIBILITY_MAXIMUM
// LOSE CUFFS
// Wait...
sleep(mist_delay / 2)
@@ -1,10 +1,10 @@
/datum/action/bloodsucker/veil
/datum/action/cooldown/bloodsucker/veil
name = "Veil of Many Faces"
desc = "Disguise yourself in the illusion of another identity."
button_icon_state = "power_veil"
bloodcost = 15
cooldown = 100
cooldown_time = 100
amToggle = TRUE
bloodsucker_can_buy = TRUE
warn_constant_cost = TRUE
@@ -29,7 +29,7 @@
var/list/prev_features // For lizards and such
/datum/action/bloodsucker/veil/CheckCanUse(display_error)
/datum/action/cooldown/bloodsucker/veil/CheckCanUse(display_error)
. = ..()
if(!.)
return
@@ -37,7 +37,7 @@
return TRUE
/datum/action/bloodsucker/veil/ActivatePower()
/datum/action/cooldown/bloodsucker/veil/ActivatePower()
cast_effect() // POOF
@@ -47,14 +47,14 @@
Disguise_FaceName()
/datum/action/bloodsucker/veil/proc/Disguise_Outfit()
/datum/action/cooldown/bloodsucker/veil/proc/Disguise_Outfit()
// Step One: Back up original items
/datum/action/bloodsucker/veil/proc/Disguise_FaceName()
/datum/action/cooldown/bloodsucker/veil/proc/Disguise_FaceName()
// Change Name/Voice
var/mob/living/carbon/human/H = owner
@@ -112,7 +112,7 @@
sleep(50)
/datum/action/bloodsucker/veil/DeactivatePower(mob/living/user = owner, mob/living/target)
/datum/action/cooldown/bloodsucker/veil/DeactivatePower(mob/living/user = owner, mob/living/target)
..()
if (ishuman(user))
var/mob/living/carbon/human/H = user
@@ -149,7 +149,7 @@
cast_effect() // POOF
// CAST EFFECT // // General effect (poof, splat, etc) when you cast. Doesn't happen automatically!
/datum/action/bloodsucker/veil/proc/cast_effect()
/datum/action/cooldown/bloodsucker/veil/proc/cast_effect()
// Effect
playsound(get_turf(owner), 'sound/magic/smoke.ogg', 20, 1)
var/datum/effect_system/steam_spread/puff = new /datum/effect_system/steam_spread/()
@@ -80,7 +80,6 @@
/datum/action/innate/cellular_emporium/New(our_target)
. = ..()
button.name = name
if(istype(our_target, /datum/cellular_emporium))
cellular_emporium = our_target
else
@@ -229,10 +229,10 @@
playsound(get_turf(owner.current), 'sound/effects/lingreadapt.ogg', 75, TRUE, 5)
can_respec = 0
SSblackbox.record_feedback("tally", "changeling_power_purchase", 1, "Readapt")
return 1
return TRUE
else
to_chat(owner.current, "<span class='danger'>You lack the power to readapt your evolutions!</span>")
return 0
return FALSE
//Called in life()
/datum/antagonist/changeling/proc/regenerate()//grants the HuD in life.dm
@@ -285,7 +285,7 @@
if(verbose)
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
return
return 1
return TRUE
/datum/antagonist/changeling/proc/create_profile(mob/living/carbon/human/H, protect = 0)
@@ -47,10 +47,10 @@ the same goes for Remove(). if you override Remove(), call parent or else your p
/datum/action/changeling/proc/sting_action(mob/user, mob/target)
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]"))
return 0
return FALSE
/datum/action/changeling/proc/sting_feedback(mob/user, mob/target)
return 0
return FALSE
//Fairly important to remember to return TRUE on success >.<
@@ -44,7 +44,7 @@
name = "Reviving Stasis"
desc = "We fall into a stasis, allowing us to regenerate and trick our enemies. Costs 15 chemicals."
button_icon_state = "fake_death"
UpdateButtonIcon()
UpdateButtons()
chemical_cost = 15
to_chat(user, "<span class='notice'>We have revived ourselves.</span>")
@@ -56,7 +56,7 @@
name = "Revive"
desc = "We arise once more."
button_icon_state = "revive"
UpdateButtonIcon()
UpdateButtons()
chemical_cost = 0
revive_ready = TRUE
@@ -94,7 +94,7 @@ GLOBAL_LIST_EMPTY(hivemind_bank)
if(first_prof.name == user.real_name)//If our current DNA is the stalest, we gotta ditch it.
to_chat(user, "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>")
return
return 1
return TRUE
/datum/action/changeling/hivemind_download/sting_action(mob/user)
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
@@ -13,7 +13,7 @@
if(!chosen_prof)
return
if(!user || user.mob_transforming)
return 0
return FALSE
to_chat(user, "<span class='notice'>We transform our appearance.</span>")
changeling.purchasedpowers -= src
@@ -40,7 +40,7 @@
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
changeling.chem_recharge_slowdown -= recharge_slowdown
user.update_inv_hands()
return 1
return TRUE
/datum/action/changeling/weapon/sting_action(mob/living/user)
var/obj/item/held = user.get_active_held_item()
@@ -325,7 +325,7 @@
..()
/obj/item/projectile/tentacle/proc/reset_throw(mob/living/carbon/human/H)
if(H.in_throw_mode)
if(H.throw_mode)
H.throw_mode_off() //Don't annoy the changeling if he doesn't catch the item
/obj/item/projectile/tentacle/proc/tentacle_grab(mob/living/carbon/human/H, mob/living/carbon/C)
@@ -597,7 +597,7 @@
/datum/action/changeling/gloves/proc/check_gloves(mob/user)
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
if(!ishuman(user) || !changeling)
return 1
return TRUE
var/mob/living/carbon/human/H = user
if(istype(H.gloves, glove_type))
H.visible_message("<span class='warning'>With a sickening crunch, [H] reforms [H.p_their()] [glove_name_simple] into hands!</span>", "<span class='warning'>We assimilate our [glove_name_simple].</span>", "<span class='italics'>You hear organic matter ripping and tearing!</span>")
@@ -609,7 +609,7 @@
playsound(H.loc, 'sound/effects/splat.ogg', 50, 1) //So real sounds
changeling.chem_recharge_slowdown -= recharge_slowdown
return 1
return TRUE
/datum/action/changeling/gloves/Remove(mob/user)
if(!ishuman(user))
@@ -53,7 +53,7 @@
if(target.mind && target.mind.has_antag_datum(/datum/antagonist/changeling))
sting_feedback(user, target)
changeling.chem_charges -= chemical_cost
return 1
return TRUE
/datum/action/changeling/sting/sting_feedback(mob/user, mob/target)
if(!target)
@@ -61,7 +61,7 @@
to_chat(user, "<span class='notice'>We stealthily sting [target.name].</span>")
if(target.mind && target.mind.has_antag_datum(/datum/antagonist/changeling))
to_chat(target, "<span class='warning'>You feel a tiny prick.</span>")
return 1
return TRUE
/datum/action/changeling/sting/transformation
@@ -94,8 +94,8 @@
return
if((HAS_TRAIT(target, TRAIT_HUSK)) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits))
to_chat(user, "<span class='warning'>Our sting appears ineffective against its DNA.</span>")
return 0
return 1
return FALSE
return TRUE
/datum/action/changeling/sting/transformation/sting_action(mob/user, mob/target)
if(ismonkey(target))
@@ -133,8 +133,8 @@
var/mob/living/L = target
if((HAS_TRAIT(L, TRAIT_HUSK)) || !L.has_dna())
to_chat(user, "<span class='warning'>Our sting appears ineffective against its DNA.</span>")
return 0
return 1
return FALSE
return TRUE
/datum/action/changeling/sting/false_armblade/sting_action(mob/user, mob/target)
log_combat(user, target, "stung", object="false armblade sting")
@@ -21,7 +21,7 @@
return ..()
user.visible_message("<span class='warning'>[user] scatters [src] with [I]!</span>", "<span class='danger'>You scatter [src] with [I]!</span>")
qdel(src)
return 1
return TRUE
return ..()
/obj/effect/clockwork/sigil/attack_tk(mob/user)
@@ -25,7 +25,7 @@
return
if(isitem(M))
var/obj/item/I = M
if(is_servant_of_ratvar(I.thrownby)) //nice try!
if(is_servant_of_ratvar(I.thrownby?.resolve())) //nice try!
return
return TRUE
@@ -16,22 +16,22 @@ drain_amount: How much is drained by default; Influenced by a multiplier on most
var/obj/item/stock_parts/cell/cell = get_cell()
if(cell)
return cell.power_drain(clockcult_user, drain_weapons, recursive, drain_amount)
return 0 //Returns 0 instead of FALSE to symbolise it returning the power amount in other cases, not TRUE aka 1
return FALSE //Returns 0 instead of FALSE to symbolise it returning the power amount in other cases, not TRUE aka 1
/obj/item/melee/baton/power_drain(clockcult_user, drain_weapons = FALSE, recursive = FALSE, drain_amount = MIN_CLOCKCULT_POWER) //balance memes
if(!drain_weapons)
return 0
return FALSE
var/obj/item/stock_parts/cell/cell = get_cell()
if(cell)
return cell.power_drain(clockcult_user, drain_weapons, recursive, drain_amount)
return 0 //No need to recurse further in batons
return FALSE //No need to recurse further in batons
/obj/item/gun/power_drain(clockcult_user, drain_weapons = FALSE, recursive = FALSE, drain_amount = MIN_CLOCKCULT_POWER) //balance memes
if(!drain_weapons)
return 0
return FALSE
var/obj/item/stock_parts/cell/cell = get_cell()
if(!cell)
return 0
return FALSE
if(cell.charge)
. = min(cell.charge, drain_amount*4) //Done snowflakey because guns have far smaller cells than batons / other equipment, also no need to recurse further in guns
cell.use(.)
@@ -40,7 +40,7 @@
/proc/generate_all_scripture()
if(GLOB.all_scripture.len)
return
for(var/V in sortList(subtypesof(/datum/clockwork_scripture) - list(/datum/clockwork_scripture/channeled, /datum/clockwork_scripture/create_object, /datum/clockwork_scripture/create_object/construct), GLOBAL_PROC_REF(cmp_clockscripture_priority)))
for(var/V in sort_list(subtypesof(/datum/clockwork_scripture) - list(/datum/clockwork_scripture/channeled, /datum/clockwork_scripture/create_object, /datum/clockwork_scripture/create_object/construct), GLOBAL_PROC_REF(cmp_clockscripture_priority)))
var/datum/clockwork_scripture/S = new V
GLOB.all_scripture[S.type] = S
@@ -25,7 +25,7 @@
/obj/item/shield/riot/ratvarian/proc/calc_bash_mult()
var/bash_mult = 0
if(!dam_absorbed)
return 1
return TRUE
else
bash_mult += round(clamp(1 + (dam_absorbed / bash_mult_steps), 1, max_bash_mult), 0.1) //Multiplies the effect of bashes by up to [max_bash_mult], though never less than one
return bash_mult
@@ -55,7 +55,7 @@
/obj/item/clothing/head/helmet/clockwork/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self)
if(equipper && !is_servant_of_ratvar(equipper))
return 0
return FALSE
return ..()
/obj/item/clothing/suit/armor/clockwork
@@ -100,7 +100,7 @@
/obj/item/clothing/suit/armor/clockwork/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self)
if(equipper && !is_servant_of_ratvar(equipper))
return 0
return FALSE
return ..()
/obj/item/clothing/suit/armor/clockwork/equipped(mob/living/user, slot)
@@ -160,7 +160,7 @@
/obj/item/clothing/gloves/clockwork/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self)
if(equipper && !is_servant_of_ratvar(equipper))
return 0
return FALSE
return ..()
/obj/item/clothing/gloves/clockwork/equipped(mob/living/user, slot)
@@ -210,7 +210,7 @@
/obj/item/clothing/shoes/clockwork/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self)
if(equipper && !is_servant_of_ratvar(equipper))
return 0
return FALSE
return ..()
/obj/item/clothing/shoes/clockwork/equipped(mob/living/user, slot)
@@ -411,6 +411,6 @@
Q.name = "[quickbind_slot.name] ([Q.scripture_index])"
Q.desc = quickbind_slot.quickbind_desc
Q.button_icon_state = quickbind_slot.name
Q.UpdateButtonIcon()
Q.UpdateButtons()
if(isliving(loc))
Q.Grant(loc)
@@ -29,7 +29,7 @@
/obj/item/clothing/glasses/judicial_visor/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot != ITEM_SLOT_EYES)
return 0
return FALSE
return ..()
/obj/item/clothing/glasses/judicial_visor/equipped(mob/living/user, slot)
@@ -38,7 +38,7 @@
update_status(FALSE)
if(blaster.ranged_ability_user)
blaster.remove_ranged_ability()
return 0
return FALSE
if(is_servant_of_ratvar(user))
update_status(TRUE)
else
@@ -48,7 +48,7 @@
to_chat(user, "<span class='userdanger'>You suddenly catch fire!</span>")
user.adjust_fire_stacks(5)
user.IgniteMob()
return 1
return TRUE
/obj/item/clothing/glasses/judicial_visor/dropped(mob/user)
. = ..()
@@ -67,27 +67,27 @@
/obj/item/clothing/glasses/judicial_visor/proc/update_status(change_to)
if(recharging || !isliving(loc))
icon_state = "judicial_visor_0"
return 0
return FALSE
if(active == change_to)
return 0
return FALSE
var/mob/living/L = loc
active = change_to
icon_state = "judicial_visor_[active]"
L.update_action_buttons_icon()
L.update_inv_glasses()
if(!is_servant_of_ratvar(L) || L.stat)
return 0
return FALSE
switch(active)
if(TRUE)
to_chat(L, "<span class='notice'>As you put on [src], its lens begins to glow, information flashing before your eyes.</span>\n\
<span class='heavy_brass'>Judicial visor active. Use the action button to gain the ability to smite the unworthy.</span>")
if(FALSE)
to_chat(L, "<span class='notice'>As you take off [src], its lens darkens once more.</span>")
return 1
return TRUE
/obj/item/clothing/glasses/judicial_visor/proc/recharge_visor(mob/living/user)
if(!src)
return 0
return FALSE
recharging = FALSE
if(user && src == user.get_item_by_slot(ITEM_SLOT_EYES))
to_chat(user, "<span class='brass'>Your [name] hums. It is ready.</span>")
@@ -23,7 +23,7 @@
/obj/item/clockwork/replica_fabricator/scarab/fabricate(atom/target, mob/living/user)
if(!debug && !isdrone(user))
return 0
return FALSE
return ..()
/obj/item/clockwork/replica_fabricator/scarab/debug
@@ -38,7 +38,7 @@
fully_heal(TRUE)
/mob/living/simple_animal/hostile/clockwork/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
return 0 //ouch, my metal-unlikely-to-be-damaged-by-electricity-body
return FALSE //ouch, my metal-unlikely-to-be-damaged-by-electricity-body
/mob/living/simple_animal/hostile/clockwork/examine(mob/user)
var/t_He = p_they(TRUE)
@@ -121,7 +121,7 @@
stat(null, "You do [melee_damage_upper] damage on melee attacks.")
/mob/living/simple_animal/hostile/clockwork/guardian/Process_Spacemove(movement_dir = 0)
return 1
return TRUE
/mob/living/simple_animal/hostile/clockwork/guardian/proc/bind_to_host(mob/living/new_host)
if(!new_host)
@@ -180,8 +180,8 @@
resulthealth = "[round((host.health / host.maxHealth) * 100, 0.5)]%"
else
resulthealth = "NONE"
G.hosthealth.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#AF0AAF'>HOST<br>[resulthealth]</font></div>"
hud_used.healths.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#AF0AAF'>[round((health / maxHealth) * 100, 0.5)]%</font>"
G.hosthealth.maptext = MAPTEXT("<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#AF0AAF'>HOST<br>[resulthealth]</font></div>")
hud_used.healths.maptext = MAPTEXT("<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#AF0AAF'>[round((health / maxHealth) * 100, 0.5)]%</font>")
/mob/living/simple_animal/hostile/clockwork/guardian/proc/update_stats()
if(GLOB.ratvar_awakens)
@@ -93,7 +93,7 @@
if(is_servant_of_ratvar(user) && I.tool_behaviour == TOOL_WRENCH && unanchored_icon)
if(default_unfasten_wrench(user, I, 50) == SUCCESSFUL_UNFASTEN)
update_anchored(user)
return 1
return TRUE
return ..()
/obj/structure/destructible/clockwork/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
@@ -37,7 +37,7 @@
if(user.canUseTopic(src, !issilicon(user), NO_DEXTERY) && is_servant_of_ratvar(user))
if(!can_access_clockwork_power(src, mania_cost))
to_chat(user, "<span class='warning'>[src] needs more power to function!</span>")
return 0
return FALSE
toggle(0, user)
/obj/structure/destructible/clockwork/powered/mania_motor/toggle(fast_process, mob/living/user)
@@ -144,10 +144,10 @@
/obj/structure/destructible/clockwork/ocular_warden/proc/lose_target()
if(!target)
return 0
return FALSE
target = null
visible_message("<span class='warning'>[src] settles and seems almost disappointed.</span>")
return 1
return TRUE
/obj/structure/destructible/clockwork/ocular_warden/get_efficiency_mod()
if(GLOB.ratvar_awakens)
@@ -43,19 +43,19 @@
to_chat(user, "<span class='brass'>You break [src] apart, refunding some of the power used.</span>")
adjust_clockwork_power(power_refund)
take_damage(max_integrity)
return 0
return FALSE
if(active)
return 0
return FALSE
var/turf/T = get_turf(src)
if(!T || !is_station_level(T.z))
to_chat(user, "<span class='warning'>[src] must be on the station to function!</span>")
return 0
return FALSE
if(SSshuttle.emergency.mode != SHUTTLE_CALL)
to_chat(user, "<span class='warning'>No emergency shuttles are attempting to arrive at the station!</span>")
return 0
return FALSE
if(!try_use_power(get_delay_cost()))
to_chat(user, "<span class='warning'>[src] needs more power to function!</span>")
return 0
return FALSE
delay_cost += delay_cost_increase
delay_remaining += PRISM_DELAY_DURATION
toggle(0, user)
@@ -81,7 +81,7 @@
density = TRUE //Skewers are one-use only
desc = "A vicious brass spike protruding from the ground like a stala[pick("gm", "ct")]ite. It makes you sick to look at." //is stalagmite the ground one? or the ceiling one? who can ever remember?
/obj/structure/destructible/clockwork/trap/brass_skewer/user_buckle_mob()
/obj/structure/destructible/clockwork/trap/brass_skewer/user_buckle_mob(check_loc)
return
/obj/structure/destructible/clockwork/trap/brass_skewer/post_buckle_mob(mob/living/L)
@@ -25,7 +25,7 @@
/obj/structure/destructible/clockwork/wall_gear/attackby(obj/item/I, mob/user, params)
if(I.tool_behaviour == TOOL_WRENCH)
default_unfasten_wrench(user, I, 10)
return 1
return TRUE
else if(I.tool_behaviour == TOOL_SCREWDRIVER)
if(anchored)
to_chat(user, "<span class='warning'>[src] needs to be unsecured to disassemble it!</span>")
@@ -34,7 +34,7 @@
if(I.use_tool(src, user, 30, volume=100) && !anchored)
to_chat(user, "<span class='notice'>You disassemble [src].</span>")
deconstruct(TRUE)
return 1
return TRUE
else if(istype(I, /obj/item/stack/tile/brass))
var/obj/item/stack/tile/brass/W = I
if(W.get_amount() < 1)
@@ -64,7 +64,7 @@
qdel(src)
else
to_chat(user, "<span class='warning'>You need more brass to make a [anchored ? "false ":""]wall!</span>")
return 1
return TRUE
return ..()
/obj/structure/destructible/clockwork/wall_gear/deconstruct(disassembled = TRUE)
+23 -22
View File
@@ -2,16 +2,11 @@
name = "Prepare Blood Magic"
button_icon_state = "carve"
desc = "Prepare blood magic by carving runes into your flesh. This rite is most effective with an <b>empowering rune</b>"
default_button_position = DEFAULT_BLOODSPELLS
var/list/spells = list()
var/channeling = FALSE
var/holy_dispel = FALSE
/datum/action/innate/cult/blood_magic/Grant()
..()
button.screen_loc = DEFAULT_BLOODSPELLS
button.moved = DEFAULT_BLOODSPELLS
button.ordered = FALSE
/datum/action/innate/cult/blood_magic/Remove()
for(var/X in spells)
qdel(X)
@@ -23,15 +18,21 @@
return ..()
/datum/action/innate/cult/blood_magic/proc/Positioning()
var/list/screen_loc_split = splittext(button.screen_loc,",")
var/list/screen_loc_X = splittext(screen_loc_split[1],":")
var/list/screen_loc_Y = splittext(screen_loc_split[2],":")
var/pix_X = text2num(screen_loc_X[2])
for(var/datum/action/innate/cult/blood_spell/B in spells)
if(B.button.locked)
var/order = pix_X+spells.Find(B)*31
B.button.screen_loc = "[screen_loc_X[1]]:[order],[screen_loc_Y[1]]:[screen_loc_Y[2]]"
B.button.moved = B.button.screen_loc
for(var/datum/hud/hud as anything in viewers)
var/our_view = hud.mymob?.client?.view || "15x15"
var/atom/movable/screen/movable/action_button/button = viewers[hud]
var/position = screen_loc_to_offset(button.screen_loc)
var/spells_iterated = 0
for(var/datum/action/innate/cult/blood_spell/blood_spell in spells)
spells_iterated += 1
if(blood_spell.positioned)
continue
var/atom/movable/screen/movable/action_button/moving_button = blood_spell.viewers[hud]
if(!moving_button)
continue
var/our_x = position[1] + spells_iterated * world.icon_size // Offset any new buttons into our list
hud.position_action(moving_button, offset_to_screen_loc(our_x, position[2], our_view))
blood_spell.positioned = TRUE
/datum/action/innate/cult/blood_magic/Activate()
if(holy_dispel)
@@ -99,6 +100,8 @@
var/base_desc //To allow for updating tooltips
var/invocation
var/health_cost = 0
/// Have we already been positioned into our starting location?
var/positioned = FALSE
/datum/action/innate/cult/blood_spell/Grant(mob/living/owner, datum/action/innate/cult/blood_magic/BM)
if(health_cost)
@@ -106,9 +109,7 @@
base_desc = desc
desc += "<br><b><u>Has [charges] use\s remaining</u></b>."
all_magic = BM
..()
button.locked = TRUE
button.ordered = FALSE
return ..()
/datum/action/innate/cult/blood_spell/Remove()
if(all_magic)
@@ -273,7 +274,7 @@
attached_action.charges--
attached_action.desc = attached_action.base_desc
attached_action.desc += "<br><b><u>Has [attached_action.charges] use\s remaining</u></b>."
attached_action.UpdateButtonIcon()
attached_action.UpdateButtons()
if(attached_action.charges <= 0)
remove_ranged_ability("<span class='cult'>You have exhausted the spell's power!</span>")
qdel(src)
@@ -325,7 +326,7 @@
qdel(src)
desc = base_desc
desc += "<br><b><u>Has [charges] use\s remaining</u></b>."
UpdateButtonIcon()
UpdateButtons()
/datum/action/innate/cult/blood_spell/manipulation
name = "Blood Rites"
@@ -373,7 +374,7 @@
source.charges = uses
source.desc = source.base_desc
source.desc += "<br><b><u>Has [uses] use\s remaining</u></b>."
source.UpdateButtonIcon()
source.UpdateButtons()
..()
/obj/item/melee/blood_magic/attack_self(mob/living/user)
@@ -400,7 +401,7 @@
else if(source)
source.desc = source.base_desc
source.desc += "<br><b><u>Has [uses] use\s remaining</u></b>."
source.UpdateButtonIcon()
source.UpdateButtons()
//Stun
/obj/item/melee/blood_magic/stun
+1 -1
View File
@@ -108,7 +108,7 @@
var/where = mob.equip_in_one_of_slots(T, slots, critical = TRUE)
if(!where)
to_chat(mob, "<span class='userdanger'>Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1).</span>")
return 0
return FALSE
else
to_chat(mob, "<span class='danger'>You have a [item_name] in your [where].</span>")
if(where == "backpack")
+1 -1
View File
@@ -142,7 +142,7 @@
/datum/action/innate/cult/master/IsAvailable(silent = FALSE)
if(!owner.mind || !owner.mind.has_antag_datum(/datum/antagonist/cult/master) || GLOB.cult_narsie)
return 0
return FALSE
return ..()
/datum/action/innate/cult/master/finalreck
+1 -2
View File
@@ -795,14 +795,13 @@
desc = "Call the blood spear back to your hand!"
background_icon_state = "bg_demon"
button_icon_state = "bloodspear"
default_button_position = "6:157,4:-2"
var/obj/item/cult_spear/spear
var/cooldown = 0
/datum/action/innate/cult/spear/Grant(mob/user, obj/blood_spear)
. = ..()
spear = blood_spear
button.screen_loc = "6:157,4:-2"
button.moved = "6:157,4:-2"
/datum/action/innate/cult/spear/Activate()
if(owner == spear.loc || cooldown > world.time)
+2 -2
View File
@@ -243,12 +243,12 @@ structure_check() searches for nearby cultist structures required for the invoca
for(var/M in invokers)
to_chat(M, "<span class='warning'>You need at least two invokers to convert [convertee]!</span>")
log_game("Offer rune failed - tried conversion with one invoker")
return 0
return FALSE
if(convertee.anti_magic_check(TRUE, TRUE, chargecost = 0)) //Not major because it can be spammed
for(var/M in invokers)
to_chat(M, "<span class='warning'>Something is shielding [convertee]'s mind!</span>")
log_game("Offer rune failed - convertee had anti-magic")
return 0
return FALSE
var/brutedamage = convertee.getBruteLoss()
var/burndamage = convertee.getFireLoss()
if(brutedamage || burndamage)
+12 -12
View File
@@ -389,43 +389,43 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
if(iscarbon(body))
var/mob/living/carbon/H = body
return H.reagents.has_reagent(/datum/reagent/water/holywater)
return 0
return FALSE
if(BANISH_COFFIN)
return (body && istype(body.loc, /obj/structure/closet/crate/coffin))
if(BANISH_FORMALDYHIDE)
if(iscarbon(body))
var/mob/living/carbon/H = body
return H.reagents.has_reagent(/datum/reagent/toxin/formaldehyde)
return 0
return FALSE
if(BANISH_RUNES)
if(body)
for(var/obj/effect/decal/cleanable/crayon/R in range(0,body))
if (R.name == "rune")
return 1
return 0
return TRUE
return FALSE
if(BANISH_CANDLES)
if(body)
var/count = 0
for(var/obj/item/candle/C in range(1,body))
count += C.lit
if(count>=4)
return 1
return 0
return TRUE
return FALSE
if(BANISH_DESTRUCTION)
if(body)
return 0
return 1
return FALSE
return TRUE
if(BANISH_FUNERAL_GARB)
if(ishuman(body))
var/mob/living/carbon/human/H = body
if(H.w_uniform && istype(H.w_uniform, /obj/item/clothing/under/misc/burial))
return 1
return 0
return TRUE
return FALSE
else
for(var/obj/item/clothing/under/misc/burial/B in range(0,body))
if(B.loc == get_turf(B)) //Make sure it's not in someone's inventory or something.
return 1
return 0
return TRUE
return FALSE
/datum/antagonist/devil/proc/hellish_resurrection(mob/living/body)
message_admins("[owner.name] (true name is: [truename]) is resurrecting using hellish energy.</a>")
@@ -35,4 +35,4 @@
DefaultCombatKnockdown(40)
qdel(weapon)
return 2
return 1
return TRUE
@@ -17,9 +17,9 @@
/datum/antagonist/sintouched/threat()
switch(sin)
if(SIN_GLUTTONY,SIN_ENVY)
return 1
return TRUE
else
return 0
return FALSE
/datum/antagonist/sintouched/New()
. = ..()
@@ -84,7 +84,7 @@
. += "</span>"
/mob/living/carbon/true_devil/IsAdvancedToolUser()
return 1
return TRUE
/mob/living/carbon/true_devil/resist_buckle()
if(buckled)
@@ -110,7 +110,7 @@
return ..() //flashes don't stop devils UNLESS it's their bane.
/mob/living/carbon/true_devil/soundbang_act()
return 0
return FALSE
/mob/living/carbon/true_devil/get_ear_protection()
return 2
@@ -124,7 +124,7 @@
/mob/living/carbon/true_devil/singularity_act()
if(ascended)
return 0
return FALSE
return ..()
//ATTACK GHOST IGNORING PARENT RETURN VALUE
@@ -138,7 +138,7 @@
return ..()
/mob/living/carbon/true_devil/can_be_revived()
return 1
return TRUE
/mob/living/carbon/true_devil/resist_fire()
//They're immune to fire.
@@ -177,7 +177,7 @@
// devils do not need to breathe
/mob/living/carbon/true_devil/is_literate()
return 1
return TRUE
/mob/living/carbon/true_devil/ex_act(severity, target, origin)
if(!ascended)
@@ -1,8 +1,8 @@
/mob/living/carbon/true_devil/doUnEquip(obj/item/I, force, silent = FALSE)
/mob/living/carbon/true_devil/doUnEquip(obj/item/I, force, invdrop, silent = FALSE)
if(..())
update_inv_hands()
return 1
return 0
return TRUE
return FALSE
/mob/living/carbon/true_devil/update_inv_hands()
//TODO LORDPIDEY: Figure out how to make the hands line up properly. the l/r_hand_overlay should use the down sprite when facing down, left, or right, and the up sprite when facing up.
@@ -170,7 +170,7 @@
to_chat(user, "<span class='warning'>These items don't possess the required fingerprints or DNA.</span>")
return FALSE
var/chosen_mob = input("Select the person you wish to curse","Your target") as null|anything in sortList(compiled_list, GLOBAL_PROC_REF(cmp_mob_realname_dsc))
var/chosen_mob = input("Select the person you wish to curse","Your target") as null|anything in sort_list(compiled_list, GLOBAL_PROC_REF(cmp_mob_realname_dsc))
if(!chosen_mob)
return FALSE
curse(compiled_list[chosen_mob])
@@ -125,7 +125,7 @@
var/datum/component/uplink/uplink = uplink_holder.GetComponent(/datum/component/uplink)
uplink.telecrystals = INITIAL_CRYSTALS
// Give AI hacking board
var/obj/item/aiModule/core/full/overthrow/O = new(H)
var/obj/item/ai_module/core/full/overthrow/O = new(H)
var/list/slots = list (
"backpack" = ITEM_SLOT_BACKPACK,
"left pocket" = ITEM_SLOT_LPOCKET,
@@ -150,7 +150,7 @@
essencecolor = "#9A5ACB" //oh boy you've got a lot of essence
else if(!essence)
essencecolor = "#1D2953" //oh jeez you're dying
hud_used.healths.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='[essencecolor]'>[essence]E</font></div>"
hud_used.healths.maptext = MAPTEXT("<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='[essencecolor]'>[essence]E</font></div>")
/mob/living/simple_animal/revenant/med_hud_set_health()
return //we use no hud
@@ -175,7 +175,7 @@
//Immunities
/mob/living/simple_animal/revenant/ex_act(severity, target, origin)
return 1 //Immune to the effects of explosions.
return TRUE //Immune to the effects of explosions.
/mob/living/simple_animal/revenant/wave_ex_act(power, datum/wave_explosion/explosion, dir)
return power
@@ -225,7 +225,7 @@
/mob/living/simple_animal/revenant/death()
if(!revealed || stasis) //Revenants cannot die if they aren't revealed //or are already dead
return 0
return FALSE
stasis = TRUE
to_chat(src, "<span class='revendanger'>NO! No... it's too late, you can feel your essence [pick("breaking apart", "drifting away")]...</span>")
mob_transforming = TRUE
@@ -333,7 +333,7 @@
to_chat(src, "<span class='revennotice'>Gained [essence_amt]E[source ? " from [source]":""].</span>")
else
to_chat(src, "<span class='revenminor'>Lost [essence_amt]E[source ? " from [source]":""].</span>")
return 1
return TRUE
/mob/living/simple_animal/revenant/proc/telekinesis_cooldown_end()
if(!telekinesis_cooldown)
@@ -176,7 +176,7 @@
user.reveal(reveal)
user.stun(stun)
if(action)
action.UpdateButtonIcon()
action.UpdateButtons()
return TRUE
//Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people.
@@ -210,7 +210,7 @@
return ..()
/obj/item/organ/heart/demon/Stop()
return 0 // Always beating.
return FALSE // Always beating.
/mob/living/simple_animal/slaughter/laughter
// The laughter demon! It's everyone's best friend! It just wants to hug

Some files were not shown because too many files have changed in this diff Show More