mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-14 16:44:33 +01:00
Changed Mob Hunt Server to be an abstract controller
Adds catch modifier support, track wild captures Adds support for capture modifiers: - These modifiers adjust the "effective run chance" of the mob, potentially making it easier or harder to capture a mob based on the total modifier - Attempting to capture a mob in melee (running up and smacking it with pda in hand) now grants a 20% capture bonus (reduces mob's effective run chance by 20) - Attempting to capture a mob at range (throwing the pda) does not grant a bonus - Support is in place for a client-based catch modifiers, to allow for possible things such as bonuses or penalties from things like "item cards" or achieving X number of captures. This is not currently planned for this PR Adds tracking of how many wild mobs you have captured to the game UI. Mobs from trading cards will not increase this value, only mob you captured from the wild will. - Bragging rights for now, but could be used for a future "milestone" system to earn bonuses More cleanup and fixes Thrown PDAs now properly trigger capture attempts Mobs now properly consider their type preferences for spawning (may need to up whitelist bonus weight) Mobs no longer will spawn in holodeck areas, since this results in them sometimes spawning on z2 in the holodeck source "templates" show_message replaced with audible_message Spawn area selection cleanup Mobs will no longer attempt to spawn in the derelict solars, constructionsite solars, or the unused /area/construction subtypes (the base type is used, just not the subtypes as far as I can tell) - Mobs will also avoid spawning on turfs that are not on the station z-level, in the event an area is mistakenly mapped onto additional z-levels or something
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
return
|
||||
|
||||
|
||||
/client/proc/debug_controller(controller in list("Master","failsafe","Ticker","Air","Lighting","Jobs","Sun","Radio","Configuration","pAI", "Cameras","Garbage", "Transfer Controller","Event","Alarm","Scheduler","Nano","Vote"))
|
||||
/client/proc/debug_controller(controller in list("Master","failsafe","Ticker","Air","Lighting","Jobs","Sun","Radio","Configuration","pAI", "Cameras","Garbage", "Transfer Controller","Event","Alarm","Scheduler","Nano","Vote","Mob Hunt Server"))
|
||||
set category = "Debug"
|
||||
set name = "Debug Controller"
|
||||
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
|
||||
@@ -76,6 +76,9 @@
|
||||
if("Vote")
|
||||
debug_variables(vote)
|
||||
feedback_add_details("admin_verb","DVote")
|
||||
if("Mob Hunt Server")
|
||||
debug_variables(mob_hunt_server)
|
||||
feedback_add_details("admin_verb","DMobHuntServer")
|
||||
|
||||
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
|
||||
return
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
var/global/datum/controller/process/mob_hunt/mob_hunt_server
|
||||
|
||||
var/global/obj/machinery/mob_hunt_server/mob_hunt_server = null
|
||||
|
||||
/obj/machinery/mob_hunt_server
|
||||
name = "Nano-Mob Hunter GO Server "
|
||||
desc = "A game server for the new hit PDA game \"Nano-Mob Hunter GO\". May be unstable."
|
||||
icon_state = "processor"
|
||||
density = 1
|
||||
anchored = 1
|
||||
/datum/controller/process/mob_hunt
|
||||
var/max_normal_spawns = 15 //change this to adjust the number of normal spawns that can exist at one time. trapped spawns (from traitors) don't count towards this
|
||||
var/list/normal_spawns = list()
|
||||
var/list/trap_spawns = list()
|
||||
@@ -14,24 +8,19 @@ var/global/obj/machinery/mob_hunt_server/mob_hunt_server = null
|
||||
var/server_instability = 0 //tracks the instability of the game server. trapped mobs and users increase instability, which causes random kicks and eventually crashing
|
||||
var/server_status = 1 //1 is online, 0 is offline
|
||||
|
||||
/obj/machinery/mob_hunt_server/New()
|
||||
..()
|
||||
if(!mob_hunt_server)
|
||||
mob_hunt_server = src
|
||||
else
|
||||
log_admin("A Nano-Mob Hunter GO server was created at ([x], [y]) on z[z] while one already exists. Deleting the new server.")
|
||||
//there can only be one!
|
||||
qdel(src)
|
||||
/datum/controller/process/mob_hunt/setup()
|
||||
name = "Nano-Mob Hunter GO Server"
|
||||
start_delay = 20
|
||||
mob_hunt_server = src
|
||||
|
||||
/obj/machinery/mob_hunt_server/Destroy()
|
||||
/datum/controller/process/mob_hunt/Destroy()
|
||||
for(var/datum/data/pda/app/mob_hunter_game/client in connected_clients)
|
||||
client.disconnect("Server Destruction")
|
||||
if(mob_hunt_server && mob_hunt_server == src)
|
||||
mob_hunt_server = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/mob_hunt_server/process()
|
||||
..()
|
||||
/datum/controller/process/mob_hunt/doWork()
|
||||
if(server_status == 0)
|
||||
return
|
||||
if(normal_spawns.len < max_normal_spawns)
|
||||
@@ -48,10 +37,10 @@ var/global/obj/machinery/mob_hunt_server/mob_hunt_server = null
|
||||
var/datum/data/pda/app/mob_hunter_game/client = pick(connected_clients)
|
||||
client.disconnect("Server Communication Error")
|
||||
|
||||
/obj/machinery/mob_hunt_server/proc/check_stability()
|
||||
/datum/controller/process/mob_hunt/proc/check_stability()
|
||||
server_instability = connected_clients.len + (trap_spawns.len * 5)
|
||||
|
||||
/obj/machinery/mob_hunt_server/proc/server_crash()
|
||||
/datum/controller/process/mob_hunt/proc/server_crash()
|
||||
server_status = 0
|
||||
for(var/datum/data/pda/app/mob_hunter_game/client in connected_clients)
|
||||
client.disconnect("Server Crash")
|
||||
@@ -66,7 +55,7 @@ var/global/obj/machinery/mob_hunt_server/mob_hunt_server = null
|
||||
//set a timer to automatically recover in 5 minutes (can be manually restarted if you get impatient too)
|
||||
addtimer(src, "auto_recover", 3000, TRUE)
|
||||
|
||||
/obj/machinery/mob_hunt_server/proc/auto_recover()
|
||||
/datum/controller/process/mob_hunt/proc/auto_recover()
|
||||
if(server_status != 0)
|
||||
return
|
||||
server_instability = 0
|
||||
@@ -74,7 +63,7 @@ var/global/obj/machinery/mob_hunt_server/mob_hunt_server = null
|
||||
while(normal_spawns.len < max_normal_spawns) //repopulate the server's spawns completely if we auto-recover from crash
|
||||
spawn_mob()
|
||||
|
||||
/obj/machinery/mob_hunt_server/proc/manual_reboot()
|
||||
/datum/controller/process/mob_hunt/proc/manual_reboot()
|
||||
for(var/obj/effect/nanomob/N in trap_spawns)
|
||||
N.despawn()
|
||||
for(var/obj/effect/nanomob/N in normal_spawns)
|
||||
@@ -82,19 +71,19 @@ var/global/obj/machinery/mob_hunt_server/mob_hunt_server = null
|
||||
check_stability()
|
||||
server_status = 1
|
||||
|
||||
/obj/machinery/mob_hunt_server/proc/spawn_mob()
|
||||
/datum/controller/process/mob_hunt/proc/spawn_mob()
|
||||
var/list/nanomob_types = subtypesof(/datum/mob_hunt)
|
||||
var/datum/mob_hunt/mob_info = pick(nanomob_types)
|
||||
new mob_info()
|
||||
|
||||
/obj/machinery/mob_hunt_server/proc/register_spawn(datum/mob_hunt/mob_info)
|
||||
/datum/controller/process/mob_hunt/proc/register_spawn(datum/mob_hunt/mob_info)
|
||||
if(!mob_info)
|
||||
return 0
|
||||
var/obj/effect/nanomob/new_mob = new /obj/effect/nanomob(mob_info.spawn_point, mob_info)
|
||||
normal_spawns += new_mob
|
||||
return 1
|
||||
|
||||
/obj/machinery/mob_hunt_server/proc/register_trap(datum/mob_hunt/mob_info)
|
||||
/datum/controller/process/mob_hunt/proc/register_trap(datum/mob_hunt/mob_info)
|
||||
if(!mob_info)
|
||||
return 0
|
||||
if(!mob_info.is_trap)
|
||||
|
||||
@@ -37,27 +37,25 @@
|
||||
return
|
||||
if(istype(O, /obj/item/device/pda))
|
||||
var/obj/item/device/pda/P = O
|
||||
if(P.current_app && istype(P.current_app, /datum/data/pda/app/mob_hunter_game))
|
||||
attempt_capture(P)
|
||||
return 1
|
||||
attempt_capture(P, -20) //attempting a melee capture reduces the mob's effective run_chance by 20% to balance the risk of triggering a trap mob
|
||||
return 1
|
||||
|
||||
/obj/effect/nanomob/hitby(obj/item/O)
|
||||
if(invisibility) //no catching mobs you can't normally see!
|
||||
return
|
||||
if(istype(O, /obj/item/device/pda))
|
||||
var/obj/item/device/pda/P = O
|
||||
if(P.current_app && istype(P.current_app, /datum/data/pda/app/mob_hunter_game))
|
||||
attempt_capture(P)
|
||||
return 1
|
||||
attempt_capture(P) //attempting a ranged capture does not affect the mob's effective run_chance but does prevent you from being shocked by a trap mob
|
||||
return 1
|
||||
|
||||
/obj/effect/nanomob/proc/attempt_capture(obj/item/device/pda/P)
|
||||
/obj/effect/nanomob/proc/attempt_capture(obj/item/device/pda/P, catch_mod = 0) //negative catch_mods lower effective run chance,
|
||||
if(!P || !P.current_app || !istype(P.current_app, /datum/data/pda/app/mob_hunter_game) || !P.cartridge)
|
||||
return
|
||||
|
||||
var/datum/data/pda/app/mob_hunter_game/client = P.current_app
|
||||
var/total_catch_mod = client.catch_mod + catch_mod //negative values decrease the chance of the mob running, positive values makes it more likely to flee
|
||||
if(!client.connected) //must be connected to attempt captures
|
||||
for(var/mob/O in hearers(4, P.loc))
|
||||
O.show_message("[bicon(P)] No server connection. Capture aborted.")
|
||||
P.audible_message("[bicon(P)] No server connection. Capture aborted.", null, 4)
|
||||
return
|
||||
|
||||
if(mob_info.is_trap) //traps work even if you ran into them before, which is why this is before the clients_encountered check
|
||||
@@ -84,16 +82,16 @@
|
||||
else //deal with the new hunter by either running away or getting caught
|
||||
clients_encountered += cart_ref
|
||||
var/message = "[bicon(P)] "
|
||||
if(mob_info.run_chance && prob(mob_info.run_chance))
|
||||
var/effective_run_chance = mob_info.run_chance + total_catch_mod
|
||||
if((effective_run_chance > 0) && prob(effective_run_chance))
|
||||
message += "Capture failed! [name] escaped [P.owner ? "from [P.owner]" : "from this hunter"]!"
|
||||
else
|
||||
if(client.register_capture(mob_info))
|
||||
if(client.register_capture(mob_info, 1))
|
||||
message += "Capture success! [P.owner ? P.owner : "This hunter"] captured [name]!"
|
||||
else
|
||||
message += "Capture error! Try again."
|
||||
clients_encountered -= cart_ref //if the capture registration failed somehow, let them have another chance with this mob
|
||||
for(var/mob/O in hearers(4, P.loc))
|
||||
O.show_message(message)
|
||||
P.audible_message(message, null, 4)
|
||||
|
||||
/obj/effect/nanomob/proc/despawn()
|
||||
if(mob_hunt_server)
|
||||
@@ -107,8 +105,6 @@
|
||||
/obj/effect/nanomob/proc/reveal()
|
||||
if(invisibility == 101)
|
||||
invisibility = 0
|
||||
//density = 1
|
||||
spawn(30)
|
||||
if(src)
|
||||
invisibility = 101
|
||||
//density = 1
|
||||
|
||||
@@ -62,6 +62,10 @@
|
||||
if(prob(1) && prob(1))
|
||||
is_shiny = 1
|
||||
health[2] = base_health + (level * health_multiplier)
|
||||
if(primary_type)
|
||||
primary_type = new primary_type()
|
||||
if(secondary_type)
|
||||
secondary_type = new secondary_type()
|
||||
if(no_register) //for booster pack cards
|
||||
return
|
||||
if(mob_hunt_server)
|
||||
@@ -101,7 +105,9 @@
|
||||
var/list/possible_areas = list()
|
||||
//setup, sets all station areas (and subtypes) to weight 1
|
||||
for(var/A in the_station_areas)
|
||||
if(istype(A, /area/holodeck)) //don't allow holodeck areas as possible spawns since it will allow it to spawn in the holodeck rooms on z2 as well
|
||||
if(A == /area/holodeck) //don't allow holodeck areas as possible spawns since it will allow it to spawn in the holodeck rooms on z2 as well
|
||||
continue
|
||||
if(A in possible_areas)
|
||||
continue
|
||||
for(var/areapath in typesof(A))
|
||||
possible_areas[areapath] = 1
|
||||
@@ -128,10 +134,16 @@
|
||||
for(var/A in area_blacklist)
|
||||
for(var/areapath in typesof(A))
|
||||
possible_areas[areapath] -= 2
|
||||
//weight check, remove negative or zero weight areas from the list, then return the list
|
||||
//removes "bad areas" which shouldn't be on-station but are subtypes of station areas. probably should the unused ones and consider repathing the rest
|
||||
var/list/bad_areas = list(subtypesof(/area/construction), /area/solar/derelict_starboard, /area/solar/derelict_aft, /area/solar/constructionsite)
|
||||
for(var/A in bad_areas)
|
||||
possible_areas -= A
|
||||
//weight check, remove negative or zero weight areas from the list, then return the list.
|
||||
for(var/areapath in possible_areas)
|
||||
//remove any areas that shouldn't be on the station-level
|
||||
if(possible_areas[areapath] < 1)
|
||||
possible_areas -= areapath
|
||||
continue
|
||||
return possible_areas
|
||||
|
||||
/datum/mob_hunt/proc/get_possible_turfs(area/spawn_area)
|
||||
@@ -140,6 +152,8 @@
|
||||
var/list/possible_turfs = list()
|
||||
//setup, sets all turfs in spawn_area to weight 1
|
||||
for(var/turf/T in spawn_area)
|
||||
if(T.z > 1) //mobs will only consider station-level turfs for spawning. Largely here so we won't have to worry about mapping errors or mobs on the derelict solars
|
||||
continue
|
||||
possible_turfs[T] = 1
|
||||
//primary type preferences
|
||||
if(primary_type)
|
||||
@@ -229,13 +243,13 @@
|
||||
if(!primary_type)
|
||||
return "Typeless"
|
||||
else
|
||||
return initial(primary_type.name)
|
||||
return primary_type.name
|
||||
|
||||
/datum/mob_hunt/proc/get_type2()
|
||||
if(!secondary_type)
|
||||
return null
|
||||
else
|
||||
return initial(secondary_type.name)
|
||||
return secondary_type.name
|
||||
|
||||
|
||||
/datum/mob_hunt/nemabug
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
var/current_index = 0
|
||||
var/connected = 0
|
||||
var/hacked = 0 //if set, this cartridge is able to spawn trap mobs from its collection (set via emag_act on the cartridge)
|
||||
var/catch_mod = 0 //used to adjust the likelihood of a mob running from this client, a negative value means it is less likely to run (support for temporary bonuses)
|
||||
var/wild_captures = 0 //used to track the total number of mobs captured from the wild (does not count card mobs) by this client
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/start()
|
||||
..()
|
||||
@@ -42,8 +44,7 @@
|
||||
mob_hunt_server.connected_clients += src
|
||||
connected = 1
|
||||
if(pda)
|
||||
for(var/mob/O in hearers(2, pda.loc))
|
||||
O.show_message("[bicon(pda)] Connection established. Capture all of the mobs, [pda.owner ? pda.owner : "hunter"]!")
|
||||
pda.audible_message("[bicon(pda)] Connection established. Capture all of the mobs, [pda.owner ? pda.owner : "hunter"]!", null, 2)
|
||||
return 1
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/proc/disconnect(reason = null)
|
||||
@@ -53,18 +54,25 @@
|
||||
connected = 0
|
||||
//show a disconnect message if we were disconnected involuntarily (reason argument provided)
|
||||
if(pda && reason)
|
||||
for(var/mob/O in hearers(2, pda.loc))
|
||||
O.show_message("[bicon(pda)] Disconnected from server. Reason: [reason].")
|
||||
pda.audible_message("[bicon(pda)] Disconnected from server. Reason: [reason].", null, 2)
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/program_process()
|
||||
if(!mob_hunt_server || !connected)
|
||||
return
|
||||
scan_nearby()
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/proc/register_capture(datum/mob_hunt/captured)
|
||||
/datum/data/pda/app/mob_hunter_game/program_hit_check()
|
||||
if(!pda)
|
||||
return
|
||||
for(var/obj/effect/nanomob/hit_mob in get_turf(pda))
|
||||
hit_mob.hitby(pda)
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/proc/register_capture(datum/mob_hunt/captured, wild = 0)
|
||||
if(!captured)
|
||||
return 0
|
||||
my_collection.Add(captured)
|
||||
if(wild)
|
||||
wild_captures++
|
||||
return 1
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/update_ui(mob/user as mob, list/data)
|
||||
@@ -72,6 +80,7 @@
|
||||
data["connected"] = 0
|
||||
else
|
||||
data["connected"] = 1
|
||||
data["wild_captures"] = wild_captures
|
||||
data["no_collection"] = 0
|
||||
if(!my_collection.len)
|
||||
data["no_collection"] = 1
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
<span class="average">Your collection is empty! Go capture some Nano-Mobs!</span>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
Wild mobs captured: {{:data.wild_captures}}
|
||||
{{else}}
|
||||
<div class="statusDisplayRecords">
|
||||
<div class="item">
|
||||
@@ -59,6 +61,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
Wild mobs captured: {{:data.wild_captures}}
|
||||
<div class="item">
|
||||
<table>
|
||||
<tr>
|
||||
|
||||
Reference in New Issue
Block a user