mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 19:47:22 +01:00
Framework for Job Objectives
This commit is contained in:
@@ -57,8 +57,18 @@
|
||||
return 0
|
||||
|
||||
|
||||
proc/spawn_result()
|
||||
proc/spawn_result(mob/user as mob)
|
||||
if(result)
|
||||
// PAY ME
|
||||
var/taskpath=null
|
||||
switch(result)
|
||||
if(/obj/mecha/working/ripley)
|
||||
taskpath = /datum/job_objective/make_ripley
|
||||
if(taskpath)
|
||||
var/datum/job_objective/task = user.mind.findJobTask(taskpath)
|
||||
if(istype(task))
|
||||
task.unit_completed()
|
||||
|
||||
new result(get_turf(holder))
|
||||
spawn()
|
||||
del holder
|
||||
|
||||
@@ -99,6 +99,15 @@ datum/mind
|
||||
output += "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
|
||||
obj_count++
|
||||
|
||||
if(job_objectives.len>0)
|
||||
output += "<HR><B>Job Objectives:</B><UL>"
|
||||
|
||||
var/obj_count = 1
|
||||
for(var/datum/job_objective/objective in job_objectives)
|
||||
output += "<LI><B>Task #[obj_count]</B>: [objective.get_description()]</LI>"
|
||||
obj_count++
|
||||
output += "</UL>"
|
||||
|
||||
recipient << browse(output,"window=memory")
|
||||
|
||||
proc/edit_memory()
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
var/explosion_in_progress = 0 //sit back and relax
|
||||
var/list/datum/mind/modePlayer = new
|
||||
var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist
|
||||
var/list/protected_jobs = list() // Jobs that can't be tratiors because
|
||||
var/list/protected_jobs = list() // Jobs that can't be trators
|
||||
var/required_players = 0
|
||||
var/required_players_secret = 0 //Minimum number of players for that game mode to be chose in Secret
|
||||
var/required_enemies = 0
|
||||
@@ -70,10 +70,6 @@ Implants;
|
||||
(Pointless) Badassery;
|
||||
/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"}
|
||||
|
||||
// Items removed from above:
|
||||
/*
|
||||
/obj/item/weapon/cloaking_device:4:Cloaking Device; //Replacing cloakers with thermals. -Pete
|
||||
*/
|
||||
|
||||
/datum/game_mode/proc/announce() //to be calles when round starts
|
||||
world << "<B>Notice</B>: [src] did not define announce()"
|
||||
@@ -122,6 +118,70 @@ Implants;
|
||||
/datum/game_mode/proc/process()
|
||||
return 0
|
||||
|
||||
//Called by the gameticker
|
||||
/datum/game_mode/proc/process_job_tasks()
|
||||
var/obj/machinery/message_server/useMS = null
|
||||
if(message_servers)
|
||||
for (var/obj/machinery/message_server/MS in message_servers)
|
||||
if(MS.active)
|
||||
useMS = MS
|
||||
break
|
||||
for(var/mob/M in player_list)
|
||||
if(M.mind)
|
||||
var/obj/item/device/pda/P=null
|
||||
for(var/obj/item/device/pda/check_pda in sortAtom(PDAs))
|
||||
if (check_pda.owner==M.name)
|
||||
P=check_pda
|
||||
break
|
||||
var/count=0
|
||||
for(var/datum/job_objective/objective in M.mind.job_objectives)
|
||||
count++
|
||||
var/msg=""
|
||||
var/pay=0
|
||||
if(objective.per_unit && objective.units_needing_compensation>0)
|
||||
var/newunits = objective.units_needing_compensation
|
||||
msg="We see that you completed [newunits] new unit[newunits>1?"s":""] for Task #[count]! "
|
||||
pay=objective.completion_payment * newunits
|
||||
else if(!objective.completed)
|
||||
if(objective.is_completed())
|
||||
pay=objective.completion_payment
|
||||
msg="Task #[count] completed! "
|
||||
if(pay>0)
|
||||
if(M.mind.initial_account)
|
||||
M.mind.initial_account.money += objective.completion_payment
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = "[command_name()] Payroll"
|
||||
T.purpose = "Payment"
|
||||
T.amount = objective.completion_payment
|
||||
T.date = current_date_string
|
||||
T.time = worldtime2text()
|
||||
T.source_terminal = "\[CLASSIFIED\] Terminal #[rand(111,333)]"
|
||||
M.mind.initial_account.transaction_log.Add(T)
|
||||
msg += "You have been sent the $[pay], as agreed."
|
||||
else
|
||||
msg += "However, we were unable to send you the $[pay] you're entitled."
|
||||
if(useMS)
|
||||
// THIS SHOULD HAVE DONE EVERYTHING FOR ME
|
||||
useMS.send_pda_message("[P.owner]", "[command_name()] Payroll", msg)
|
||||
|
||||
// BUT NOPE, NEED TO DO THIS BULLSHIT.
|
||||
P.tnote += "<i><b>← From [command_name()] (Payroll):</b></i><br>[msg]<br>"
|
||||
|
||||
if (!P.silent)
|
||||
playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
for (var/mob/O in hearers(3, P.loc))
|
||||
if(!P.silent) O.show_message(text("\icon[P] *[P.ttone]*"))
|
||||
//Search for holder of the PDA.
|
||||
var/mob/living/L = null
|
||||
if(P.loc && isliving(P.loc))
|
||||
L = P.loc
|
||||
//Maybe they are a pAI!
|
||||
else
|
||||
L = get(P, /mob/living/silicon)
|
||||
|
||||
if(L)
|
||||
L << "\icon[P] <b>Message from [command_name()] (Payroll), </b>\"[msg]\" (<i>Unable to Reply</i>)"
|
||||
break
|
||||
|
||||
/datum/game_mode/proc/check_finished() //to be called by ticker
|
||||
if(emergency_shuttle.location==2 || station_was_nuked)
|
||||
|
||||
@@ -298,6 +298,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
return 0
|
||||
|
||||
mode.process()
|
||||
mode.process_job_tasks()
|
||||
|
||||
emergency_shuttle.process()
|
||||
|
||||
@@ -366,6 +367,8 @@ var/global/datum/controller/gameticker/ticker
|
||||
|
||||
mode.declare_completion()//To declare normal completion.
|
||||
|
||||
mode.declare_job_completion()
|
||||
|
||||
//calls auto_declare_completion_* for all modes
|
||||
for(var/handler in typesof(/datum/game_mode/proc))
|
||||
if (findtext("[handler]","auto_declare_completion_"))
|
||||
|
||||
@@ -41,6 +41,12 @@
|
||||
//If you have use_age_restriction_for_jobs config option enabled and the database set up, this option will add a requirement for players to be at least minimal_player_age days old. (meaning they first signed in at least that many days before.)
|
||||
var/minimal_player_age = 0
|
||||
|
||||
/////////////////////////////////
|
||||
// /vg/ feature: Job Objectives!
|
||||
/////////////////////////////////
|
||||
var/required_objectives=list() // Objectives that are ALWAYS added.
|
||||
var/optional_objectives=list() // Objectives that are SOMETIMES added.
|
||||
|
||||
/datum/job/proc/equip(var/mob/living/carbon/human/H)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch)
|
||||
minimal_player_age = 7
|
||||
|
||||
// All science-y guys get bonuses for maxing out their tech.
|
||||
required_objectives=list(
|
||||
/datum/job_objective/maximize_research
|
||||
)
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
if(!H) return 0
|
||||
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/rd(H), slot_ears)
|
||||
@@ -49,6 +54,11 @@
|
||||
minimal_access = list(access_tox, access_tox_storage, access_research, access_xenoarch)
|
||||
alt_titles = list("Xenoarcheologist", "Anomalist", "Plasma Researcher")
|
||||
|
||||
// All science-y guys get bonuses for maxing out their tech.
|
||||
required_objectives=list(
|
||||
/datum/job_objective/maximize_research
|
||||
)
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
if(!H) return 0
|
||||
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sci(H), slot_ears)
|
||||
@@ -76,6 +86,12 @@
|
||||
access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology)
|
||||
minimal_access = list(access_research, access_xenobiology)
|
||||
|
||||
// All science-y guys get bonuses for maxing out their tech.
|
||||
required_objectives=list(
|
||||
/datum/job_objective/maximize_research
|
||||
)
|
||||
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
if(!H) return 0
|
||||
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sci(H), slot_ears)
|
||||
@@ -103,6 +119,12 @@
|
||||
minimal_access = list(access_robotics, access_tech_storage, access_morgue, access_research) //As a job that handles so many corpses, it makes sense for them to have morgue access.
|
||||
alt_titles = list("Biomechanical Engineer","Mechatronic Engineer")
|
||||
|
||||
required_objectives=list(
|
||||
/datum/job_objective/make_cyborg,
|
||||
// /datum/job_objective/make_mommi,
|
||||
/datum/job_objective/make_ripley
|
||||
)
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
if(!H) return 0
|
||||
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sci(H), slot_ears)
|
||||
|
||||
@@ -59,6 +59,17 @@ var/global/datum/controller/occupations/job_master
|
||||
Debug("Player: [player] is now Rank: [rank], JCP:[job.current_positions], JPL:[position_limit]")
|
||||
player.mind.assigned_role = rank
|
||||
player.mind.role_alt_title = GetPlayerAltTitle(player, rank)
|
||||
|
||||
// JOB OBJECTIVES OH SHIT
|
||||
player.mind.job_objectives.Cut()
|
||||
for(var/objectiveType in job.required_objectives)
|
||||
new objectiveType(player.mind)
|
||||
|
||||
// 50/50 chance of getting optional objectives.
|
||||
for(var/objectiveType in job.optional_objectives)
|
||||
if(prob(50))
|
||||
new objectiveType(player.mind)
|
||||
|
||||
unassigned -= player
|
||||
job.current_positions++
|
||||
return 1
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/datum/mind/var/list/job_objectives=list()
|
||||
|
||||
#define FINDJOBTASK_DEFAULT_NEW 1 // Make a new task of this type if one can't be found.
|
||||
/datum/mind/proc/findJobTask(var/typepath,var/options)
|
||||
var/datum/job_objective/task = locate(typepath) in src.job_objectives
|
||||
if(!istype(task,typepath))
|
||||
if(options & FINDJOBTASK_DEFAULT_NEW)
|
||||
task = new typepath()
|
||||
src.job_objectives += task
|
||||
return task
|
||||
else
|
||||
return null
|
||||
|
||||
/datum/job_objective
|
||||
var/datum/mind/owner = null //Who owns the objective.
|
||||
var/completed = 0 //currently only used for custom objectives.
|
||||
var/per_unit = 0
|
||||
var/units_completed = 0
|
||||
var/units_needing_compensation = 0 // Shit not yet paid for
|
||||
var/units_requested = INFINITY
|
||||
var/completion_payment = 0 // Credits paid to owner when completed
|
||||
|
||||
/datum/job_objective/New(var/datum/mind/new_owner)
|
||||
owner=new_owner
|
||||
owner.job_objectives += src
|
||||
|
||||
/datum/job_objective/Del()
|
||||
|
||||
/datum/job_objective/proc/get_description()
|
||||
return "Placeholder objective."
|
||||
|
||||
/datum/job_objective/proc/unit_completed(var/count=1)
|
||||
units_completed += count
|
||||
units_needing_compensation += count
|
||||
|
||||
/datum/job_objective/proc/is_completed()
|
||||
if(!completed)
|
||||
completed = check_for_completion()
|
||||
return completed
|
||||
|
||||
/datum/job_objective/proc/check_for_completion()
|
||||
return 0
|
||||
|
||||
/datum/game_mode/proc/declare_job_completion()
|
||||
var/text = "<FONT size = 2><B>Job Completion:</B></FONT>"
|
||||
for(var/datum/mind/employee in player_list)
|
||||
if(!employee.job_objectives.len)//If the employee had no objectives, don't need to process this.
|
||||
return
|
||||
var/tasks_completed=0
|
||||
|
||||
//text += "<b>[L.name]</b> ([ckey(D.mind.key)]), the [L.job]:\n"
|
||||
text += "<br>[employee.key] was [employee.name] ("
|
||||
if(employee.current)
|
||||
if(employee.current.stat == DEAD)
|
||||
text += "died"
|
||||
else
|
||||
text += "survived"
|
||||
if(employee.current.real_name != employee.name)
|
||||
text += " as [employee.current.real_name]"
|
||||
else
|
||||
text += "body destroyed"
|
||||
text += ")"
|
||||
|
||||
var/count = 1
|
||||
for(var/datum/job_objective/objective in employee.job_objectives)
|
||||
if(objective.is_completed(1))
|
||||
text += "<br><B>Task #[count]</B>: [objective.get_description()] <font color='green'><B>Completed!</B></font>"
|
||||
feedback_add_details("employee_objective","[objective.type]|SUCCESS")
|
||||
tasks_completed++
|
||||
else
|
||||
text += "<br><B>Task #[count]</B>: [objective.get_description()] <font color='red'>Fail.</font>"
|
||||
feedback_add_details("employee_objective","[objective.type]|FAIL")
|
||||
count++
|
||||
|
||||
if(tasks_completed>=1)
|
||||
text += "<br><font color='green'><B>The [employee.assigned_role] did their fucking job!</B></font>"
|
||||
feedback_add_details("employee_success","SUCCESS")
|
||||
else
|
||||
text += "<br><font color='red'><B>The [employee.assigned_role] was a worthless sack of shit!</B></font>"
|
||||
feedback_add_details("employee_success","FAIL")
|
||||
|
||||
world << text
|
||||
return 1
|
||||
@@ -0,0 +1,60 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Research
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// MAXIMUM SCIENCE
|
||||
/datum/job_objective/maximize_research
|
||||
completion_payment=1000
|
||||
|
||||
/datum/job_objective/maximize_research/get_description()
|
||||
return "Maximize all legal research tech levels."
|
||||
|
||||
/datum/job_objective/maximize_research/check_for_completion()
|
||||
var/obj/machinery/r_n_d/server/server = null
|
||||
for(var/obj/machinery/r_n_d/server/serber in machines)
|
||||
if(serber.name == "Core R&D Server")
|
||||
server=serber
|
||||
break
|
||||
if(!server)
|
||||
// This was just used for testing.
|
||||
//world << "UNABLE TO FIND A GODDAMN RND SERVER. FUCK."
|
||||
return
|
||||
for(var/datum/tech/T in server.files.possible_tech)
|
||||
if(T.max_level==0) // Ignore illegal tech, etc
|
||||
continue
|
||||
var/datum/tech/KT = locate(T.type, server.files.known_tech)
|
||||
if(!KT)
|
||||
return 0 // Obviously haven't maxed everything if we don't know a tech.
|
||||
if(KT.level<T.max_level)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Robotics
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Mek cyburg
|
||||
/datum/job_objective/make_cyborg
|
||||
completion_payment=100
|
||||
per_unit=1
|
||||
|
||||
/datum/job_objective/make_cyborg/get_description()
|
||||
return "Make a cyborg. ([units_completed] created.)"
|
||||
/*
|
||||
// Mek MoMMI
|
||||
/datum/job_objective/make_mommi
|
||||
completion_payment=150
|
||||
per_unit=1
|
||||
|
||||
/datum/job_objective/make_mommi/get_description()
|
||||
return "Make a Mobile MMI. ([units_completed] created.)"
|
||||
*/
|
||||
// Mek Ripley
|
||||
/datum/job_objective/make_ripley
|
||||
completion_payment=600
|
||||
per_unit=1
|
||||
|
||||
/datum/job_objective/make_ripley/get_description()
|
||||
return "Make a Ripley. ([units_completed] created.)"
|
||||
|
||||
|
||||
@@ -199,6 +199,10 @@
|
||||
|
||||
user.drop_item()
|
||||
|
||||
var/datum/job_objective/make_cyborg/task = user.mind.findJobTask(/datum/job_objective/make_cyborg)
|
||||
if(istype(task))
|
||||
task.unit_completed()
|
||||
|
||||
O.mmi = W
|
||||
O.invisibility = 0
|
||||
O.custom_name = created_name
|
||||
|
||||
@@ -48,6 +48,12 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
|
||||
req_access = list(access_tox) //Data and setting manipulation requires scientist access.
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/Maximize()
|
||||
|
||||
files.known_tech=files.possible_tech
|
||||
for(var/datum/tech/KT in files.known_tech)
|
||||
if(KT.level < KT.max_level)
|
||||
KT.level=KT.max_level
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/CallTechName(var/ID) //A simple helper proc to find the name of a tech with a given ID.
|
||||
var/datum/tech/check_tech
|
||||
@@ -211,6 +217,15 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
updateUsrDialog()
|
||||
griefProtection() //Update centcomm too
|
||||
|
||||
else if(href_list["hax"]) // aww shit
|
||||
if(!usr.client.holder) return
|
||||
screen = 0.0
|
||||
spawn(50)
|
||||
Maximize()
|
||||
screen = 1.0
|
||||
updateUsrDialog()
|
||||
griefProtection() //Update centcomm too
|
||||
|
||||
else if(href_list["clear_tech"]) //Erase data on the technology disk.
|
||||
t_disk.stored = null
|
||||
|
||||
@@ -599,6 +614,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
if(linked_destroy != null) dat += "<A href='?src=\ref[src];menu=2.2'>Destructive Analyzer Menu</A><BR>"
|
||||
if(linked_lathe != null) dat += "<A href='?src=\ref[src];menu=3.1'>Protolathe Construction Menu</A><BR>"
|
||||
if(linked_imprinter != null) dat += "<A href='?src=\ref[src];menu=4.1'>Circuit Construction Menu</A><BR>"
|
||||
if(user.client.holder) dat += "<A href='?src=\ref[src];hax=1'>MAXIMUM SCIENCE</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];menu=1.6'>Settings</A>"
|
||||
|
||||
if(1.1) //Research viewer
|
||||
|
||||
@@ -173,6 +173,7 @@ datum/tech //Datum of individual technologies.
|
||||
var/desc = "description" //General description of what it does and what it makes.
|
||||
var/id = "id" //An easily referenced ID. Must be alphanumeric, lower-case, and no symbols.
|
||||
var/level = 1 //A simple number scale of the research level. Level 0 = Secret tech.
|
||||
var/max_level = 1 // Maximum level this can be at (for job objectives)
|
||||
var/list/req_tech = list() //List of ids associated values of techs required to research this tech. "id" = #
|
||||
|
||||
|
||||
@@ -182,51 +183,61 @@ datum/tech/materials
|
||||
name = "Materials Research"
|
||||
desc = "Development of new and improved materials."
|
||||
id = "materials"
|
||||
max_level=6
|
||||
|
||||
datum/tech/engineering
|
||||
name = "Engineering Research"
|
||||
desc = "Development of new and improved engineering parts and."
|
||||
id = "engineering"
|
||||
max_level=5
|
||||
|
||||
datum/tech/plasmatech
|
||||
name = "Plasma Research"
|
||||
desc = "Research into the mysterious substance colloqually known as 'plasma'."
|
||||
id = "plasmatech"
|
||||
max_level=3
|
||||
|
||||
datum/tech/powerstorage
|
||||
name = "Power Manipulation Technology"
|
||||
desc = "The various technologies behind the storage and generation of electicity."
|
||||
id = "powerstorage"
|
||||
max_level=6
|
||||
|
||||
datum/tech/bluespace
|
||||
name = "'Blue-space' Research"
|
||||
desc = "Research into the sub-reality known as 'blue-space'"
|
||||
id = "bluespace"
|
||||
max_level=10
|
||||
|
||||
datum/tech/biotech
|
||||
name = "Biological Technology"
|
||||
desc = "Research into the deeper mysteries of life and organic substances."
|
||||
id = "biotech"
|
||||
max_level=7
|
||||
|
||||
datum/tech/combat
|
||||
name = "Combat Systems Research"
|
||||
desc = "The development of offensive and defensive systems."
|
||||
id = "combat"
|
||||
max_level=6
|
||||
|
||||
datum/tech/magnets
|
||||
name = "Electromagnetic Spectrum Research"
|
||||
desc = "Research into the electromagnetic spectrum. No clue how they actually work, though."
|
||||
id = "magnets"
|
||||
max_level=5
|
||||
|
||||
datum/tech/programming
|
||||
name = "Data Theory Research"
|
||||
desc = "The development of new computer and artificial intelligence and data storage systems."
|
||||
id = "programming"
|
||||
max_level=4
|
||||
|
||||
datum/tech/syndicate
|
||||
name = "Illegal Technologies Research"
|
||||
desc = "The study of technologies that violate standard Nanotrasen regulations."
|
||||
id = "syndicate"
|
||||
max_level=0 // Don't count towards maxed research, since it's illegal.
|
||||
|
||||
/*
|
||||
datum/tech/arcane
|
||||
|
||||
Reference in New Issue
Block a user