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:
FalseIncarnate
2016-09-08 12:44:26 -04:00
parent 89fe9a7e81
commit 6c4bce1eac
6 changed files with 66 additions and 51 deletions
+4 -1
View File
@@ -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
+15 -26
View File
@@ -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)
+11 -15
View File
@@ -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
+18 -4
View File
@@ -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
+14 -5
View File
@@ -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
+4
View File
@@ -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>