Merge pull request #5631 from FalseIncarnate/pogo

Nano-Mob Hunter GO!
This commit is contained in:
Crazy Lemon
2016-12-29 22:58:01 -08:00
committed by GitHub
25 changed files with 1805 additions and 33 deletions
@@ -0,0 +1,278 @@
/obj/machinery/computer/mob_battle_terminal
name = "Nano-Mob Hunter GO! Battle Terminal"
desc = "Insert a mob card to partake in life-like Nano-Mob Battle Action!"
icon_state = "mob_battle_empty"
icon_screen = null
icon_keyboard = null
density = 0
anchored = 1
var/obj/item/weapon/nanomob_card/card
var/datum/mob_hunt/mob_info
var/obj/effect/nanomob/battle/avatar
var/ready = 0
var/team = "Grey"
var/avatar_x_offset = 4
var/avatar_y_offset = 0
/obj/machinery/computer/mob_battle_terminal/red
pixel_y = 24
dir = SOUTH
team = "Red"
avatar_y_offset = -1
/obj/machinery/computer/mob_battle_terminal/blue
pixel_y = -24
dir = NORTH
team = "Blue"
avatar_y_offset = 1
/obj/machinery/computer/mob_battle_terminal/red/initialize()
..()
check_connection()
/obj/machinery/computer/mob_battle_terminal/blue/initialize()
..()
check_connection()
/obj/machinery/computer/mob_battle_terminal/update_icon()
if(card)
icon_state = "mob_battle_loaded"
else
icon_state = "mob_battle_empty"
..()
/obj/machinery/computer/mob_battle_terminal/Destroy()
eject_card(1)
if(mob_hunt_server)
if(mob_hunt_server.battle_turn)
mob_hunt_server.battle_turn = null
if(mob_hunt_server.red_terminal == src)
mob_hunt_server.red_terminal = null
if(mob_hunt_server.blue_terminal == src)
mob_hunt_server.blue_terminal = null
if(avatar)
qdel(avatar)
return ..()
/obj/machinery/computer/mob_battle_terminal/attackby(obj/item/O, mob/user)
if(istype(O, /obj/item/weapon/nanomob_card))
insert_card(O, user)
/obj/machinery/computer/mob_battle_terminal/proc/insert_card(obj/item/weapon/nanomob_card/new_card, mob/user)
if(!new_card)
return
if(card)
to_chat(user, "<span class='warning'>The card slot is currently filled.</span>")
return
if(!new_card.mob_data)
to_chat(user, "<span class='danger'>This is a blank mob card.</span>")
return
if(new_card.mob_data && !new_card.mob_data.cur_health)
to_chat(user, "<span class='warning'>This mob is incapacitated! Heal it before attempting to use it in battle!</span>")
return
user.unEquip(new_card)
new_card.forceMove(src)
card = new_card
mob_info = card.mob_data
update_icon()
update_avatar()
updateUsrDialog()
/obj/machinery/computer/mob_battle_terminal/proc/eject_card(override = 0)
if(!override)
if(ready && mob_hunt_server.battle_turn != team)
audible_message("You can't recall on your rival's turn!", null, 2)
return
card.mob_data = mob_info
mob_info = null
card.forceMove(get_turf(src))
card = null
update_avatar()
update_icon()
updateUsrDialog()
/obj/machinery/computer/mob_battle_terminal/proc/update_avatar()
//if we don't have avatars yet, spawn them
if(!avatar)
avatar = new(locate((x + avatar_x_offset), (y + avatar_y_offset), z))
//update avatar info from card
if(mob_info)
avatar.mob_info = mob_info
else
avatar.mob_info = null
//tell the avatar to update themself with the new info
avatar.update_self()
/obj/machinery/computer/mob_battle_terminal/attack_hand(mob/user)
add_fingerprint(user)
interact(user)
/obj/machinery/computer/mob_battle_terminal/attack_ai(mob/user)
to_chat(user, "<span class='warning'>You cannot interface with this portion of the simulation.</span>")
return
/obj/machinery/computer/mob_battle_terminal/interact(mob/user)
check_connection()
var/dat = ""
dat += "<table border='1' style='width:75%'>"
dat += "<tr>"
dat += "<td>"
dat += "[team] PLAYER"
dat += "</td>"
dat += "</tr>"
dat += "<tr>"
dat += "<td>"
if(!card)
dat += "<h1>No Nano-Mob card loaded.</h1>"
dat += "</td>"
dat += "</tr>"
if(ready && mob_hunt_server.battle_turn) //offer the surrender option if they are in a battle (ready), but don't have a card loaded
dat += "<tr>"
dat += "<td><a href='?src=[UID()];surrender=1'>Surrender!</a></td>"
dat += "</tr>"
else
dat += "<table>"
dat += "<tr>"
dat += "<td>"
dat += "<h1>[mob_info.mob_name]</h1>"
dat += "</td>"
if(mob_info.nickname)
dat += "<td rowspan='2'>"
else
dat += "<td>"
var/img_src = "[mob_info.icon_state_normal].png"
if(mob_info.is_shiny)
dat += "[mob_info.icon_state_shiny].png"
dat += "<img src='[img_src]'>"
dat += "</td>"
dat += "</tr>"
if(mob_info.nickname)
dat += "<tr>"
dat += "<td>"
dat += "<h2>[mob_info.nickname]</h2>"
dat += "</td>"
dat += "</tr>"
dat += "</table>"
dat += "<hr>"
dat += "Health: [mob_info.cur_health] / [mob_info.max_health]<br>"
dat += "<table border='1'>"
dat += "<tr>"
if(mob_info.cur_health)
dat += "<td><a href='?src=[UID()];attack=1'>Attack!</a></td>"
else
dat += "<td>Incapacitated!</td>"
dat += "<td><a href='?src=[UID()];eject=1'>Recall!</a></td>"
dat += "</tr>"
dat += "</table>"
dat += "</td>"
dat += "</tr>"
if(!ready)
dat += "<tr>"
dat += "<td><a href='?src=[UID()];ready=1'>Battle!</a></td>"
dat += "</tr>"
if(ready && !mob_hunt_server.battle_turn)
dat += "<tr>"
dat += "<td><a href='?src=[UID()];ready=2'>Cancel Battle!</a></td>"
dat += "</tr>"
dat += "</table>"
var/datum/browser/popup = new(user, "mob_battle_terminal", "Nano-Mob Hunter GO! Battle Terminal", 575, 400)
popup.set_content(dat)
popup.open()
/obj/machinery/computer/mob_battle_terminal/Topic(href, href_list)
if(..())
return 1
if(href_list["attack"])
do_attack()
if(href_list["eject"])
eject_card()
if(href_list["surrender"])
surrender()
if(href_list["ready"])
var/option = text2num(href_list["ready"])
if(option == 1)
start_battle()
else if(option == 2)
ready = 0
audible_message("[team] Player cancels their battle challenge.", null, 5)
updateUsrDialog()
/obj/machinery/computer/mob_battle_terminal/proc/check_connection()
if(team == "Red")
if(mob_hunt_server && !mob_hunt_server.red_terminal)
mob_hunt_server.red_terminal = src
else if(team == "Blue")
if(mob_hunt_server && !mob_hunt_server.blue_terminal)
mob_hunt_server.blue_terminal = src
/obj/machinery/computer/mob_battle_terminal/proc/do_attack()
if(!ready) //no attacking if you arent ready to fight (duh)
return
if(!mob_hunt_server || team != mob_hunt_server.battle_turn) //don't attack unless it is actually our turn
return
else
var/message = "[mob_info.mob_name] attacks!"
if(mob_info.nickname)
message = "[mob_info.nickname] attacks!"
audible_message(message, null, 5)
mob_hunt_server.launch_attack(team, mob_info.get_raw_damage(), mob_info.get_attack_type())
/obj/machinery/computer/mob_battle_terminal/proc/start_battle()
if(ready) //don't do anything if we are still ready
return
if(!card) //don't do anything if there isn't a card inserted
return
ready = 1
audible_message("[team] Player is ready for battle! Waiting for rival...", null, 5)
mob_hunt_server.start_check()
/obj/machinery/computer/mob_battle_terminal/proc/receive_attack(raw_damage, datum/mob_type/attack_type)
var/message = mob_info.take_damage(raw_damage, attack_type)
avatar.audible_message(message, null, 5)
if(!mob_info.cur_health)
mob_hunt_server.end_battle(team)
eject_card(1) //force the card out, they were defeated
else
mob_hunt_server.end_turn()
/obj/machinery/computer/mob_battle_terminal/proc/surrender()
audible_message("[team] Player surrenders the battle!", null, 5)
mob_hunt_server.end_battle(team, 1)
//////////////////////////////
// Mob Healing Terminal //
// (Pokemon Center) //
//////////////////////////////
/obj/machinery/computer/mob_healer_terminal
name = "Nano-Mob Hunter GO! Restoration Terminal"
desc = "Swipe a mob card to instantly restore it to full health!"
icon_state = "mob_battle_loaded"
icon_screen = null
icon_keyboard = null
density = 0
anchored = 1
dir = EAST
/obj/machinery/computer/mob_healer_terminal/attackby(obj/item/O, mob/user)
if(istype(O, /obj/item/weapon/nanomob_card))
heal_card(O, user)
/obj/machinery/computer/mob_healer_terminal/proc/heal_card(obj/item/weapon/nanomob_card/patient, mob/user)
if(!patient)
return
if(!patient.mob_data)
to_chat(user, "<span class='danger'>This is a blank mob card.</span>")
return
if(patient.mob_data && patient.mob_data.cur_health == patient.mob_data.max_health)
to_chat(user, "<span class='warning'>This mob is already at maximum health!</span>")
return
patient.mob_data.cur_health = patient.mob_data.max_health
to_chat(user, "<span class='notify'>[patient.mob_data.nickname ? patient.mob_data.nickname : patient.mob_data.mob_name] has been restored to full health!</span>")
+162
View File
@@ -0,0 +1,162 @@
/obj/effect/nanomob
name = "Nano-Mob Avatar" //will be overridden by the mob datum name value when created
desc = "A wild Nano-Mob appeared! Hit it with your PDA with the game open to attempt to capture it!"
invisibility = 101
alpha = 128
anchored = 1 //just in case
density = 0
icon = 'icons/effects/mob_hunt.dmi'
var/state_name
var/datum/mob_hunt/mob_info = null
var/list/clients_encountered = list() //tracks who has already interacted with us, so they can't attempt a second capture
var/image/avatar
/obj/effect/nanomob/New(loc, datum/mob_hunt/new_info)
..()
if(!new_info)
qdel(src)
return
mob_info = new_info
update_self()
forceMove(mob_info.spawn_point)
if(!mob_info.is_trap)
addtimer(src, "despawn", mob_info.lifetime)
/obj/effect/nanomob/proc/update_self()
if(!mob_info)
return
name = mob_info.mob_name
desc = "A wild [name] (level [mob_info.level]) appeared! Hit it with your PDA with the game open to attempt to capture it!"
if(mob_info.is_shiny)
state_name = mob_info.icon_state_shiny
else
state_name = mob_info.icon_state_normal
avatar = image(icon, src, state_name)
avatar.override = 1
add_alt_appearance("nanomob_avatar", avatar)
/obj/effect/nanomob/attackby(obj/item/O, mob/user)
if(istype(O, /obj/item/device/pda))
var/obj/item/device/pda/P = O
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(istype(O, /obj/item/device/pda))
var/obj/item/device/pda/P = O
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, 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
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
if(client.hacked) //hacked copies of the game (copies capable of setting traps) are protected from traps
return
if(iscarbon(P.loc))
var/mob/living/carbon/C = P.loc
//Strike them down with a lightning bolt to complete the illusion (copied from the surge reagent overdose, probably could make this a general-use proc in the future)
playsound(get_turf(C), 'sound/effects/eleczap.ogg', 75, 1)
var/icon/I=new('icons/obj/zap.dmi',"lightningend")
I.Turn(-135)
var/obj/effect/overlay/beam/B = new(get_turf(C))
B.pixel_x = rand(-20, 0)
B.pixel_y = rand(-20, 0)
B.icon = I
//then actually do the damage/stun
C.electrocute_act(20, P, 1) //same damage as a revenant's overload ability, except subject to gloves/species shock resistance (for human mobs at least)
return
if(client in clients_encountered) //we've already dealt with you, go away!
return
else //deal with the new hunter by either running away or getting caught
clients_encountered += client
var/message = "[bicon(P)] "
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"]!"
conceal(client)
else
if(client.register_capture(mob_info, 1))
message += "Capture success! [P.owner ? P.owner : "This hunter"] captured [name]!"
conceal(client)
else
message += "Capture error! Try again."
clients_encountered -= client //if the capture registration failed somehow, let them have another chance with this mob
P.audible_message(message, null, 4)
/obj/effect/nanomob/proc/despawn()
if(mob_hunt_server)
if(mob_info.is_trap)
mob_hunt_server.trap_spawns -= src
else
mob_hunt_server.normal_spawns -= src
qdel(src)
/obj/effect/nanomob/proc/reveal()
if(!mob_hunt_server)
return
var/list/show_to = list()
for(var/A in mob_hunt_server.connected_clients)
if((A in clients_encountered) || !mob_hunt_server.connected_clients[A])
continue
show_to |= mob_hunt_server.connected_clients[A]
display_alt_appearance("nanomob_avatar", show_to)
/obj/effect/nanomob/proc/conceal(list/hide_from)
if(!mob_hunt_server)
return
var/list/hiding_from = list()
if(hide_from)
hiding_from = hide_from
else
for(var/A in mob_hunt_server.connected_clients)
if((A in clients_encountered) && mob_hunt_server.connected_clients[A])
hiding_from |= mob_hunt_server.connected_clients[A]
hide_alt_appearance("nanomob_avatar", hiding_from)
// BATTLE MOB AVATARS
/obj/effect/nanomob/battle
name = "Nano-Mob Battle Avatar"
desc = "A new challenger approaches!"
invisibility = 0
icon_state = "placeholder"
var/obj/machinery/computer/mob_battle_terminal/my_terminal
/obj/effect/nanomob/battle/New(loc, datum/mob_hunt/new_info)
if(new_info)
mob_info = new_info
update_self()
/obj/effect/nanomob/battle/update_self()
if(!mob_info)
name = "Nano-Mob Battle Avatar"
desc = "A new challenger approaches"
icon_state = "placeholder"
else
name = mob_info.mob_name
desc = "A tamed [name] (level [mob_info.level]) ready for battle!"
if(mob_info.is_shiny)
icon_state = mob_info.icon_state_shiny
else
icon_state = mob_info.icon_state_normal
/obj/effect/nanomob/battle/attempt_capture(obj/item/device/pda/P, catch_mod = 0)
//you can't capture battle avatars, since they belong to someone already
return
//battle avatars are always visible, so we can ignore reveal and conceal calls for them
/obj/effect/nanomob/battle/reveal()
return
/obj/effect/nanomob/battle/conceal()
return
+43
View File
@@ -0,0 +1,43 @@
//Standard Cards
/obj/item/weapon/nanomob_card
name = "Nano-Mob Hunter Trading Card"
desc = "A blank Nano-Mob Hunter Trading Card. Worthless!"
icon = 'icons/obj/card.dmi'
icon_state = "trade_card"
force = 0
throwforce = 1
w_class = 1
var/datum/mob_hunt/mob_data
/obj/item/weapon/nanomob_card/proc/update_info()
if(!mob_data)
return
if(mob_data.is_shiny)
name = "Holographic [mob_data.mob_name] Nano-Mob Hunter Card"
desc = "WOW! A holographic trading card containing a level [mob_data.level] [mob_data.mob_name]!"
icon_state = "trade_card_holo"
else
name = "[mob_data.mob_name] Nano-Mob Hunter Card"
desc = "A trading card containing a level [mob_data.level] [mob_data.mob_name]!"
//Booster Pack Cards (random mob data)
/obj/item/weapon/nanomob_card/booster
name = "Nano-Mob Hunter Booster Pack Card"
desc = "A random Nano-Mob Trading Card from a Booster Pack. Wonder what it is?"
/obj/item/weapon/nanomob_card/booster/New()
var/datum/mob_hunt/mob_info = pick(subtypesof(/datum/mob_hunt))
mob_data = new mob_info(0,null,1)
update_info()
//Booster Packs (Box of booster pack cards)
/obj/item/weapon/storage/box/nanomob_booster_pack
name = "Nano-Mob Hunter Trading Card Booster Pack"
desc = "Contains 6 random Nano-Mob Hunter Trading Cards. May contain a holographic card!"
can_hold = list("/obj/item/weapon/nanomob_card")
/obj/item/weapon/storage/box/nanomob_booster_pack/New()
..()
for(var/i in 1 to 6)
new /obj/item/weapon/nanomob_card/booster(src)
+501
View File
@@ -0,0 +1,501 @@
#define TYPE_FIRE /datum/mob_type/fire
#define TYPE_WATER /datum/mob_type/water
#define TYPE_GRASS /datum/mob_type/grass
#define TYPE_ELECTRIC /datum/mob_type/electric
#define TYPE_GROUND /datum/mob_type/ground
#define TYPE_ROCK /datum/mob_type/rock
#define TYPE_BUG /datum/mob_type/bug
#define TYPE_POISON /datum/mob_type/poison
#define TYPE_NORMAL /datum/mob_type/normal
#define TYPE_FIGHTING /datum/mob_type/fighting
#define TYPE_PSYCHIC /datum/mob_type/psychic
#define TYPE_GHOST /datum/mob_type/ghost
#define TYPE_ICE /datum/mob_type/ice
#define TYPE_FLYING /datum/mob_type/flying
#define TYPE_BLUESPACE /datum/mob_type/bluespace
#define TYPE_DARK /datum/mob_type/dark
#define TYPE_STEEL /datum/mob_type/steel
/datum/mob_hunt
//GENERAL STATS AND VARIABLES
var/mob_name = "Generic Mob" //the mob's original name (its species/type/whatever)
var/nickname = "" //the mob's nickname (if given by the owner)
var/run_chance = 0 //percent chance the mob will escape capture attempts (higher is obviously more likely to get away)
//COMBAT STATS AND VARIABLES
var/level = 0 //actual level of this mob (don't set this, it gets overwritten in New())
var/min_level = 1 //minimum level of this mob (used for randomizing the actual level)
var/max_level = 1 //maximum level of this mob (used for randomizing the actual level)
var/exp = 0 //number of battles the mob has won towards the next level (resets to 0 on level-up)
var/exp_to_level = 3 //number of battles the mob must win to level up (in case we want to make some mobs harder or easier to level)
//the types of the mob will be used for battles to determine damage resistance or weakness (mob_type_datums.dm)
var/datum/mob_type/primary_type //Make sure you set this or the mob will be unable to deal damage and will take absurd damage in battles
var/datum/mob_type/secondary_type //Don't set if not a dual-type mob so the mob will only calculate damage based on primary type
var/base_attack = 5 //base damage dealt by the mob's attacks for battling (effectively damage dealt at level 0)
var/base_health = 5 //base health of the mob for battling (effectively max health at level 0)
var/attack_multiplier = 1 //how much additional damage per level the mob deals (level * attack_multiplier)
var/health_multiplier = 1 //how much additional health per level the mob gets (level * health_multiplier) for calculating max health
var/cur_health = 0
var/max_health = 0
//SPAWN PREFERENCES AND VARIABLES
//A note on mob spawn preferences: The mob types also have preferences, which are handled prior to per-mob preferences, so ultimately you use a combined set of preferences
var/list/area_blacklist = list() //list of areas this mob can NOT spawn in (such as the bridge)
var/list/turf_blacklist = list() //list of turfs this mob can NOT spawn on (such as wood floors)
var/list/area_whitelist = list() //list of areas this mob is more likely to spawn in (can be used to reinclude subtypes of blacklisted areas)
var/list/turf_whitelist = list() //list of turfs this mob is more likely to spawn on (can be used to reinclude subtypes of blacklisted turfs)
var/turf/spawn_point //gets set and sent to the game server to spawn its avatar (generated in select_spawn or assigned via set_trap)
var/lifetime = 6000 //number of deciseconds the mob will remain before despawning (REMEMBER: DECISECONDS! So 6000 is 600 seconds which is 10 minutes)
var/is_shiny = 0 //if this gets set at spawn (super rare), the mob is considered "shiny" and will use the shiny icon_state and holographic cards
//the icon file for mob_hunt stuff is 'icons/effects/mob_hunt.dmi' so reference that for the following vars
var/icon_state_normal = "placeholder" //the icon_state for this mob's normal version
var/icon_state_shiny = "placeholder" //the icon_state for this mob's rare shiney version
var/is_trap = 0 //if this gets set, the mob is a booby-trap and will electrocute any players that dare attempt to catch it
/datum/mob_hunt/New(set_trap = 0, turf/trap_turf = null, no_register = 0)
if(set_trap)
level = max_level
is_trap = 1
spawn_point = trap_turf
else
level = rand(min_level, max_level)
if(prob(1) && prob(1))
is_shiny = 1
max_health = base_health + (level * health_multiplier)
cur_health = max_health
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)
if(set_trap)
if(mob_hunt_server.register_trap(src))
return
else if(select_spawn())
if(mob_hunt_server.register_spawn(src))
return
qdel(src) //if you reach this, the datum is just pure clutter, so delete it
/datum/mob_hunt/proc/select_spawn()
var/list/possible_areas = get_possible_areas()
if(!possible_areas.len)
log_admin("No possible areas to spawn [type] found. Possible code/mapping error?")
return 0
while(possible_areas.len)
//randomly select an area from our possible_areas list to try spawning in, then remove it from possible_areas so it won't get picked over and over forever.
var/area/spawn_area = locate(pickweight(possible_areas))
possible_areas -= spawn_area
if(!spawn_area)
break
//clear and generate a fresh list of turfs in the selected area, weighted based on white/black lists
var/list/possible_turfs = get_possible_turfs(spawn_area)
if(!possible_turfs.len) //If we don't have any possible turfs, this attempt was a failure. Try again.
continue
//if we got this far, we're spawning on this attempt, hooray!
spawn_point = pickweight(possible_turfs)
break
if(!spawn_point)
//if we get to this, we failed every attempt to find a suitable turf for EVERY area in our list of possible areas. DAMN.
log_admin("No acceptable turfs to spawn [type] on could be located. Possible code/mapping error, or someone replaced/destroyed all the acceptable turf types?")
return 0
return 1
/datum/mob_hunt/proc/get_possible_areas()
var/list/possible_areas = list()
//setup, sets all station areas (and subtypes) to weight 1
for(var/A in the_station_areas)
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
//primary type preferences
if(primary_type)
for(var/A in primary_type.area_whitelist)
for(var/areapath in typesof(A))
possible_areas[areapath] += 4
for(var/A in primary_type.area_blacklist)
for(var/areapath in typesof(A))
possible_areas[areapath] -= 2
//secondary type preferences
if(secondary_type)
for(var/A in secondary_type.area_whitelist)
for(var/areapath in typesof(A))
possible_areas[areapath] += 4
for(var/A in secondary_type.area_blacklist)
for(var/areapath in typesof(A))
possible_areas[areapath] -= 2
//mob preferences
for(var/A in area_whitelist)
for(var/areapath in typesof(A))
possible_areas[areapath] += 4
for(var/A in area_blacklist)
for(var/areapath in typesof(A))
possible_areas[areapath] -= 2
//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)
if(!spawn_area)
return list()
var/list/possible_turfs = list()
//setup, sets all turfs in spawn_area to weight 1
for(var/turf/T in spawn_area)
if(!is_station_level(T.z)) //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)
if(is_type_in_list(T, primary_type.turf_whitelist))
possible_turfs[T] += 4
if(is_type_in_list(T, primary_type.turf_blacklist))
possible_turfs[T] -= 2
//secondary type preferences
if(secondary_type)
if(is_type_in_list(T, secondary_type.turf_whitelist))
possible_turfs[T] += 4
if(is_type_in_list(T, secondary_type.turf_blacklist))
possible_turfs[T] -= 2
//mob preferences
if(is_type_in_list(T, turf_whitelist))
possible_turfs[T] += 4
if(is_type_in_list(T, turf_blacklist))
possible_turfs[T] -= 2
//weight check, remove negative or zero weight turfs from the list, then return the list
if(possible_turfs[T] < 1)
possible_turfs -= T
return possible_turfs
/datum/mob_hunt/proc/calc_def_multiplier(datum/mob_type/attack_type)
if(!primary_type)
return 99 //typeless mobs are weak to everything since they shouldn't exist
if(!attack_type) //typeless attacks will return a multiplier of 1 in case we want to use this for calculating unmodified damage for some reason (UI maybe?)
return 1
var/multiplier = 1
if(attack_type in primary_type.immunity)
return 0 //a single immunity negates all damage
else if(attack_type in primary_type.resistance)
multiplier *= 0.5
else if(attack_type in primary_type.weakness)
multiplier *= 2
else
multiplier *= 1
if(!secondary_type) //if we don't have a second type, we're done here
return multiplier
if(attack_type in secondary_type.immunity)
return 0 //a single immunity negates all damage
else if(attack_type in secondary_type.resistance)
multiplier *= 0.5
else if(attack_type in secondary_type.weakness)
multiplier *= 2
else
multiplier *= 1
return multiplier
/datum/mob_hunt/proc/take_damage(raw_damage, datum/mob_type/attack_type)
var/message = ""
var/multiplier = calc_def_multiplier(attack_type)
var/total_damage = raw_damage * multiplier
if(!cur_health) //it's already downed, quit hitting it
return null
if(!total_damage)
message += "The attack is completely ineffective! "
else
cur_health = max(cur_health - total_damage, 0)
switch(multiplier)
if(0)
message += "The attack is completely ineffective! "
if(0.25)
message += "It's barely effective... "
if(0.5)
message += "It's not very effective... "
if(2)
message += "It's super effective! "
if(4)
message += "It's ultra effective! "
if(99)
message += pick("REKT! ", "DUNKED! ", "DEFENSE BREAK! ", "WOMBO-COMBO'D!")
if(!cur_health)
message += "[nickname ? nickname : mob_name] is downed!"
return message
/datum/mob_hunt/proc/get_raw_damage()
return (level * attack_multiplier)
/datum/mob_hunt/proc/get_attack_type()
var/datum/mob_type/attack_type = primary_type
if(secondary_type && prob(40))
attack_type = secondary_type
return attack_type
/datum/mob_hunt/proc/gain_exp()
exp++
var/message = "[nickname ? nickname : mob_name] gained EXP! ([exp] / [exp_to_level] EXP)"
if(exp >= exp_to_level)
message = levelup()
return message
/datum/mob_hunt/proc/levelup()
var/message = ""
level++
exp = 0
if(level > max_level) //This is where we would trigger an evolution, when those are added (need to add evolved forms first)
level = max_level //for now though, we'll just cap them back at their max_level
message += "[nickname ? nickname : mob_name] can't get any stronger right now!"
else
max_health = base_health + (level * health_multiplier)
cur_health = max_health //full heal on level-up
message += "[nickname ? nickname : mob_name] has reached level [level]!"
return message
/datum/mob_hunt/proc/get_type1()
if(!primary_type)
return "Typeless"
else
return primary_type.name
/datum/mob_hunt/proc/get_type2()
if(!secondary_type)
return null
else
return secondary_type.name
/datum/mob_hunt/nemabug
mob_name = "Nemabug"
run_chance = 50
min_level = 1
max_level = 10
primary_type = TYPE_BUG
icon_state_normal = "nemabug"
icon_state_shiny = "nemabug_shiny"
lifetime = 6000
/datum/mob_hunt/stoutquill
mob_name = "Stoutquill"
run_chance = 50
min_level = 5
max_level = 15
primary_type = TYPE_ICE
icon_state_normal = "stoutquill"
icon_state_shiny = "stoutquill_shiny"
lifetime = 4500
/datum/mob_hunt/spectra
mob_name = "Spectra"
run_chance = 35
min_level = 1
max_level = 10
primary_type = TYPE_POISON
icon_state_normal = "spectra"
icon_state_shiny = "spectra_shiny"
lifetime = 6000
/datum/mob_hunt/dunny
mob_name = "Dunny"
run_chance = 35
min_level = 1
max_level = 10
primary_type = TYPE_FIRE
icon_state_normal = "dunny"
icon_state_shiny = "dunny_shiny"
lifetime = 6000
/datum/mob_hunt/buffsel
mob_name = "Buffsel"
run_chance = 35
min_level = 1
max_level = 10
primary_type = TYPE_ROCK
icon_state_normal = "buffsel"
icon_state_shiny = "buffsel_shiny"
lifetime = 6000
/datum/mob_hunt/quarrel
mob_name = "Quarrel"
run_chance = 35
min_level = 1
max_level = 10
primary_type = TYPE_NORMAL
icon_state_normal = "quarrel"
icon_state_shiny = "quarrel_shiny"
lifetime = 6000
/datum/mob_hunt/vulerrt
mob_name = "Vulerrt"
run_chance = 50
min_level = 5
max_level = 15
primary_type = TYPE_DARK
icon_state_normal = "vulerrt"
icon_state_shiny = "vulerrt_shiny"
turf_whitelist = list()
lifetime = 4500
/datum/mob_hunt/strudel
mob_name = "Strudel"
run_chance = 35
min_level = 1
max_level = 10
primary_type = TYPE_ELECTRIC
icon_state_normal = "strudel"
icon_state_shiny = "strudel_shiny"
lifetime = 4500
/datum/mob_hunt/folstick
mob_name = "Folstick"
run_chance = 35
min_level = 1
max_level = 10
primary_type = TYPE_WATER
icon_state_normal = "folstick"
icon_state_shiny = "folstick_shiny"
lifetime = 6000
/datum/mob_hunt/glimmerflare
mob_name = "Glimmerflare"
run_chance = 50
min_level = 5
max_level = 15
primary_type = TYPE_PSYCHIC
icon_state_normal = "glimmerflare"
icon_state_shiny = "glimmerflare_shiny"
lifetime = 4500
/datum/mob_hunt/leecoon
mob_name = "Leecoon"
run_chance = 35
min_level = 1
max_level = 10
primary_type = TYPE_GRASS
icon_state_normal = "leecoon"
icon_state_shiny = "leecoon_shiny"
lifetime = 6000
/datum/mob_hunt/halk
mob_name = "Halk"
run_chance = 35
min_level = 1
max_level = 10
primary_type = TYPE_FLYING
icon_state_normal = "halk"
icon_state_shiny = "halk_shiny"
lifetime = 6000
/datum/mob_hunt/gooby
mob_name = "Gooby"
run_chance = 65
min_level = 5
max_level = 20
primary_type = TYPE_ELECTRIC
secondary_type = TYPE_BUG
icon_state_normal = "gooby"
icon_state_shiny = "gooby_shiny"
lifetime = 3000
/datum/mob_hunt/pandoom
mob_name = "Pandoom"
run_chance = 50
min_level = 5
max_level = 15
primary_type = TYPE_GHOST
icon_state_normal = "pandoom"
icon_state_shiny = "pandoom_shiny"
lifetime = 4500
/datum/mob_hunt/relish
mob_name = "Relish"
run_chance = 65
min_level = 5
max_level = 20
primary_type = TYPE_FIRE
secondary_type = TYPE_GROUND
icon_state_normal = "relish"
icon_state_shiny = "relish_shiny"
lifetime = 3000
/datum/mob_hunt/xofine
mob_name = "Xofine"
run_chance = 50
min_level = 5
max_level = 10
primary_type = TYPE_FIRE
secondary_type = TYPE_NORMAL
icon_state_normal = "xofine"
icon_state_shiny = "xofine_shiny"
lifetime = 3000
/datum/mob_hunt/gitten
mob_name = "Gitten"
run_chance = 65
min_level = 5
max_level = 20
primary_type = TYPE_WATER
secondary_type = TYPE_POISON
icon_state_normal = "gitten"
icon_state_shiny = "gitten_shiny"
lifetime = 3000
/datum/mob_hunt/nai
mob_name = "Nai"
run_chance = 65
min_level = 5
max_level = 20
primary_type = TYPE_GRASS
secondary_type = TYPE_NORMAL
icon_state_normal = "nai"
icon_state_shiny = "nai_shiny"
lifetime = 3000
/datum/mob_hunt/pyroghast
mob_name = "Pyroghast"
run_chance = 65
min_level = 5
max_level = 20
primary_type = TYPE_FIRE
secondary_type = TYPE_GHOST
icon_state_normal = "pyroghast"
icon_state_shiny = "pyroghast"
lifetime = 4500
/datum/mob_hunt/starslam
mob_name = "Starslam"
run_chance = 65
min_level = 5
max_level = 20
primary_type = TYPE_FIGHTING
secondary_type = TYPE_ICE
icon_state_normal = "starslam"
icon_state_shiny = "starslam_shiny"
lifetime = 2500
/datum/mob_hunt/pheron
mob_name = "Pheron"
run_chance = 85
min_level = 10
max_level = 20
primary_type = TYPE_BLUESPACE
icon_state_normal = "pheron"
icon_state_shiny = "pheron_shiny"
area_blacklist = list()
turf_blacklist = list()
area_whitelist = list()
turf_whitelist = list()
lifetime = 2000
@@ -0,0 +1,256 @@
/datum/mob_type
var/name = "Typeless"
var/list/weakness = list()
var/list/resistance = list()
var/list/immunity = list()
//Type-based spawn preferences (to eliminate copy-pasting the same area and turf lists on each mob type)
var/list/area_blacklist = list() //areas to be avoided
var/list/area_whitelist = list() //areas to be more preferred
var/list/turf_blacklist = list() //turf types to be avoided
var/list/turf_whitelist = list() //turf types to be more preferred
//Type defines, to avoid spelling mistakes
/datum/mob_type/fire
name = "Fire"
weakness = list(TYPE_WATER,
TYPE_ROCK,
TYPE_GROUND)
resistance = list(TYPE_BUG,
TYPE_FIRE,
TYPE_GRASS,
TYPE_ICE,
TYPE_STEEL)
area_blacklist = list(/area/crew_quarters/toilet,
/area/crew_quarters/sleep_male/toilet_male,
/area/crew_quarters/sleep_female/toilet_female,
/area/crew_quarters/locker/locker_toilet,
/area/toxins/server_coldroom)
area_whitelist = list(/area/maintenance/turbine,
/area/maintenance/incinerator,
/area/crew_quarters/kitchen)
turf_blacklist = list(/turf/simulated/floor/beach/water)
/datum/mob_type/water
name = "Water"
weakness = list(TYPE_ELECTRIC,
TYPE_GRASS)
resistance = list(TYPE_FIRE,
TYPE_ICE,
TYPE_STEEL,
TYPE_WATER)
area_blacklist = list(/area/maintenance/turbine,
/area/maintenance/incinerator,
/area/crew_quarters/kitchen)
area_whitelist = list(/area/crew_quarters/toilet,
/area/crew_quarters/sleep_male/toilet_male,
/area/crew_quarters/sleep_female/toilet_female,
/area/crew_quarters/locker/locker_toilet)
turf_whitelist = list(/turf/simulated/floor/beach/water)
/datum/mob_type/grass
name = "Grass"
weakness = list(TYPE_FIRE,
TYPE_BUG,
TYPE_POISON,
TYPE_ICE,
TYPE_FLYING)
resistance = list(TYPE_WATER,
TYPE_GRASS,
TYPE_ELECTRIC,
TYPE_GROUND)
area_blacklist = list(/area/toxins)
area_whitelist = list(/area/hydroponics,
/area/hallway/secondary/construction)
turf_whitelist = list(/turf/simulated/floor/grass)
/datum/mob_type/electric
name = "Electric"
weakness = list(TYPE_GROUND)
resistance = list(TYPE_ELECTRIC,
TYPE_FLYING,
TYPE_STEEL)
area_whitelist = list(/area/engine,
/area/toxins/server,
/area/maintenance,
/area/turret_protected/ai,
/area/turret_protected/ai_upload,
/area/turret_protected/aisat_interior,
/area/aisat,
/area/assembly)
turf_whitelist = list(/turf/simulated/floor/bluegrid)
/datum/mob_type/ground
name = "Ground"
weakness = list(TYPE_WATER,
TYPE_GRASS,
TYPE_ICE)
resistance = list(TYPE_ROCK,
TYPE_POISON)
immunity = list(TYPE_ELECTRIC)
/datum/mob_type/rock
name = "Rock"
weakness = list(TYPE_WATER,
TYPE_GRASS,
TYPE_GROUND,
TYPE_FIGHTING,
TYPE_STEEL)
resistance = list(TYPE_FIRE,
TYPE_FLYING,
TYPE_POISON,
TYPE_NORMAL)
area_whitelist = list(/area/quartermaster,
/area/maintenance/disposal)
turf_whitelist = list(/turf/simulated/wall,
/turf/simulated/floor/mineral)
/datum/mob_type/bug
name = "Bug"
weakness = list(TYPE_FIRE,
TYPE_ROCK,
TYPE_FLYING)
resistance = list(TYPE_GRASS,
TYPE_GROUND,
TYPE_FIGHTING)
area_blacklist = list(/area/toxins)
area_whitelist = list(/area/hydroponics,
/area/hallway/secondary/construction)
turf_whitelist = list(/turf/simulated/floor/grass)
/datum/mob_type/poison
name = "Poison"
weakness = list(TYPE_GROUND,
TYPE_PSYCHIC)
resistance = list(TYPE_GRASS,
TYPE_BUG,
TYPE_POISON,
TYPE_FIGHTING)
area_blacklist = list(/area/medical,
/area/security/medbay,
/area/janitor)
area_whitelist = list(/area/medical/virology,
/area/toxins,
/area/medical/research,
/area/medical/research_shuttle_dock,
/area/crew_quarters/hor,
/area/maintenance/asmaint2)
/datum/mob_type/normal
name = "Normal"
weakness = list(TYPE_FIGHTING)
immunity = list(TYPE_GHOST)
/datum/mob_type/fighting
name = "Fighting"
weakness = list(TYPE_PSYCHIC,
TYPE_FLYING)
resistance = list(TYPE_ROCK,
TYPE_BUG,
TYPE_DARK)
area_blacklist = list(/area/medical)
area_whitelist = list(/area/crew_quarters/bar,
/area/crew_quarters/fitness,
/area/security)
turf_whitelist = list(/turf/simulated/floor/wood)
/datum/mob_type/psychic
name = "Psychic"
weakness = list(TYPE_BUG,
TYPE_GHOST,
TYPE_DARK)
resistance = list(TYPE_FIGHTING,
TYPE_PSYCHIC)
area_blacklist = list(/area/toxins,
/area/medical/research,
/area/medical/research_shuttle_dock,
/area/crew_quarters/hor,
/area/maintenance/asmaint2,
/area/teleporter,
/area/gateway)
area_whitelist = list(/area/library,
/area/chapel,
/area/medical/psych)
/datum/mob_type/ghost
name = "Ghost"
weakness = list(TYPE_GHOST,
TYPE_DARK)
resistance = list(TYPE_BUG,
TYPE_POISON)
immunity = list(TYPE_NORMAL,
TYPE_FIGHTING)
area_whitelist = list(/area/medical/morgue,
/area/chapel,
/area/medical/genetics_cloning)
/datum/mob_type/ice
name = "Ice"
weakness = list(TYPE_FIRE,
TYPE_ROCK,
TYPE_FIGHTING,
TYPE_STEEL)
resistance = list(TYPE_ICE)
area_blacklist = list(/area/maintenance/turbine,
/area/maintenance/incinerator,
/area/crew_quarters/kitchen)
area_whitelist = list(/area/toxins/server_coldroom)
/datum/mob_type/flying
name = "Flying"
weakness = list(TYPE_ELECTRIC,
TYPE_ROCK,
TYPE_ICE)
resistance = list(TYPE_GRASS,
TYPE_BUG,
TYPE_FIGHTING)
immunity = list(TYPE_GROUND)
area_blacklist = list(/area/maintenance)
area_whitelist = list(/area/hallway,
/area/escapepodbay,
/area/engine/mechanic_workshop,
/area/security/podbay)
/datum/mob_type/bluespace
name = "Bluespace"
weakness = list(TYPE_ICE,
TYPE_BLUESPACE)
resistance = list(TYPE_FIRE,
TYPE_WATER,
TYPE_GRASS,
TYPE_ELECTRIC)
/datum/mob_type/dark
name = "Dark"
weakness = list(TYPE_BUG,
TYPE_FIGHTING)
resistance = list(TYPE_GHOST,
TYPE_DARK)
immunity = list(TYPE_PSYCHIC)
area_blacklist = list(/area/solar,
/area/maintenance/auxsolarport,
/area/maintenance/starboardsolar,
/area/maintenance/portsolar,
/area/maintenance/auxsolarstarboard,
/area/clownoffice)
area_whitelist = list(/area/maintenance,
/area/assembly/assembly_line,
/area/mimeoffice)
turf_blacklist = list(/turf/simulated/floor/light)
/datum/mob_type/steel
name = "Steel"
weakness = list(TYPE_FIRE,
TYPE_GROUND,
TYPE_FIGHTING)
resistance = list(TYPE_GRASS,
TYPE_ROCK,
TYPE_BUG,
TYPE_NORMAL,
TYPE_PSYCHIC,
TYPE_ICE,
TYPE_FLYING,
TYPE_BLUESPACE,
TYPE_STEEL)
immunity = list(TYPE_POISON)
+6
View File
@@ -190,6 +190,12 @@ var/global/datum/prizes/global_prizes = new
typepath = /obj/item/weapon/spellbook/oneuse/fake_gib
cost = 100
/datum/prize_item/nanomob_booster
name = "Nano-Mob Hunter Trading Card Booster Pack"
desc = "Contains 6 random Nano-Mob Hunter Trading Cards. May contain a holographic card!"
typepath = /obj/item/weapon/storage/box/nanomob_booster_pack
cost = 100
/datum/prize_item/capgun
name = "Capgun Revolver"
desc = "Do you feel lucky... punk?"
+20 -1
View File
@@ -261,6 +261,8 @@ proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE)
send_asset_list(client, uncommon)
send_asset_list(client, common)
//Pill sprites for UIs
/datum/asset/chem_master
var/assets = list()
var/verify = FALSE
@@ -274,4 +276,21 @@ proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE)
register_asset(asset_name, assets[asset_name])
/datum/asset/chem_master/send(client)
send_asset_list(client,assets,verify)
send_asset_list(client, assets, verify)
//Mob Hunt sprites for UIs
/datum/asset/mob_hunt
var/assets = list()
var/verify = FALSE
/datum/asset/mob_hunt/register()
for(var/state in icon_states('icons/effects/mob_hunt.dmi'))
if(state == "Placeholder")
continue
assets["[state].png"] = icon('icons/effects/mob_hunt.dmi', state)
for(var/asset_name in assets)
register_asset(asset_name, assets[asset_name])
/datum/asset/mob_hunt/send(client)
send_asset_list(client, assets, verify)
@@ -74,3 +74,8 @@
/datum/gear/skullbandana
display_name = "bandana, skull"
path = /obj/item/clothing/mask/bandana/skull
/datum/gear/mob_hunt_game
display_name = "Nano-Mob Hunter GO! Cartridge"
path = /obj/item/weapon/cartridge/mob_hunt_game
cost = 2
+12
View File
@@ -427,6 +427,9 @@ var/global/list/obj/item/device/pda/PDAs = list()
user.drop_item()
C.forceMove(src)
to_chat(user, "<span class='notice'>You slide \the [C] into \the [src].</span>")
else if(istype(C, /obj/item/weapon/nanomob_card))
if(cartridge && istype(cartridge, /obj/item/weapon/cartridge/mob_hunt_game))
cartridge.attackby(C, user, params)
/obj/item/device/pda/attack(mob/living/C as mob, mob/living/user as mob)
if(istype(C, /mob/living/carbon) && scanmode)
@@ -498,3 +501,12 @@ var/global/list/obj/item/device/pda/PDAs = list()
else
close(usr)
return 0
/obj/item/device/pda/process()
if(current_app)
current_app.program_process()
/obj/item/device/pda/hit_check(speed)
if(current_app)
current_app.program_hit_check()
..()
+13 -1
View File
@@ -1,6 +1,6 @@
// Base class for anything that can show up on home screen
/datum/data/pda
var/icon = "tasks"
var/icon = "tasks" //options comes from http://fontawesome.io/icons/
var/notify_icon = "exclamation-circle"
var/notify_silent = 0
var/hidden = 0 // program not displayed in main menu
@@ -12,6 +12,16 @@
return ..()
/datum/data/pda/proc/start()
return
/datum/data/pda/proc/stop()
return
/datum/data/pda/proc/program_process()
return
/datum/data/pda/proc/program_hit_check()
return
/datum/data/pda/proc/notify(message, blink = 1)
if(message)
@@ -56,6 +66,8 @@
title = name
/datum/data/pda/app/start()
if(pda.current_app)
pda.current_app.stop()
pda.current_app = src
return 1
+41 -24
View File
@@ -22,7 +22,7 @@
if(radio)
radio.initialize()
..()
/obj/item/weapon/cartridge/Destroy()
if(radio)
qdel(radio)
@@ -53,8 +53,7 @@
/obj/item/weapon/cartridge/atmos
name = "BreatheDeep Cartridge"
icon_state = "cart-a"
programs = list(
new/datum/data/pda/utility/scanmode/gas)
programs = list(new/datum/data/pda/utility/scanmode/gas)
/obj/item/weapon/cartridge/medical
name = "Med-U Cartridge"
@@ -66,8 +65,7 @@
/obj/item/weapon/cartridge/chemistry
name = "ChemWhiz Cartridge"
icon_state = "cart-chem"
programs = list(
new/datum/data/pda/utility/scanmode/reagent)
programs = list(new/datum/data/pda/utility/scanmode/reagent)
/obj/item/weapon/cartridge/security
name = "R.O.B.U.S.T. Cartridge"
@@ -94,30 +92,25 @@
name = "CustodiPRO Cartridge"
desc = "The ultimate in clean-room design."
icon_state = "cart-j"
programs = list(
new/datum/data/pda/app/janitor)
programs = list(new/datum/data/pda/app/janitor)
/obj/item/weapon/cartridge/lawyer
name = "P.R.O.V.E. Cartridge"
icon_state = "cart-s"
programs = list(
new/datum/data/pda/app/crew_records/security)
programs = list(new/datum/data/pda/app/crew_records/security)
/obj/item/weapon/cartridge/clown
name = "Honkworks 5.0"
icon_state = "cart-clown"
charges = 5
programs = list(
new/datum/data/pda/utility/honk)
messenger_plugins = list(
new/datum/data/pda/messenger_plugin/virus/clown)
programs = list(new/datum/data/pda/utility/honk)
messenger_plugins = list(new/datum/data/pda/messenger_plugin/virus/clown)
/obj/item/weapon/cartridge/mime
name = "Gestur-O 1000"
icon_state = "cart-mi"
charges = 5
messenger_plugins = list(
new/datum/data/pda/messenger_plugin/virus/mime)
messenger_plugins = list(new/datum/data/pda/messenger_plugin/virus/mime)
/*
/obj/item/weapon/cartridge/botanist
@@ -129,8 +122,7 @@
/obj/item/weapon/cartridge/signal
name = "generic signaler cartridge"
desc = "A data cartridge with an integrated radio signaler module."
programs = list(
new/datum/data/pda/app/signaller)
programs = list(new/datum/data/pda/app/signaller)
/obj/item/weapon/cartridge/signal/initialize()
radio = new /obj/item/radio/integrated/signal(src)
@@ -162,8 +154,7 @@
/obj/item/weapon/cartridge/head
name = "Easy-Record DELUXE"
icon_state = "cart-h"
programs = list(
new/datum/data/pda/app/status_display)
programs = list(new/datum/data/pda/app/status_display)
/obj/item/weapon/cartridge/hop
name = "HumanResources9001"
@@ -303,12 +294,38 @@
icon_state = "cart"
var/initial_remote_door_id = "smindicate" //Make sure this matches the syndicate shuttle's shield/door id!! //don't ask about the name, testing.
charges = 4
programs = list(
new/datum/data/pda/utility/toggle_door)
messenger_plugins = list(
new/datum/data/pda/messenger_plugin/virus/detonate)
programs = list(new/datum/data/pda/utility/toggle_door)
messenger_plugins = list(new/datum/data/pda/messenger_plugin/virus/detonate)
/obj/item/weapon/cartridge/syndicate/New()
var/datum/data/pda/utility/toggle_door/D = programs[1]
if(istype(D))
D.remote_door_id = initial_remote_door_id
D.remote_door_id = initial_remote_door_id
/obj/item/weapon/cartridge/mob_hunt_game
name = "Nano-Mob Hunter GO! Cartridge"
desc = "The hit new PDA game that lets you track down and capture your favorite Nano-Mobs living in your world!"
icon_state = "cart-eye"
programs = list(new/datum/data/pda/app/mob_hunter_game)
var/emagged = 0
/obj/item/weapon/cartridge/mob_hunt_game/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/weapon/nanomob_card))
var/obj/item/weapon/nanomob_card/card = O
var/datum/data/pda/app/mob_hunter_game/my_game = programs[1]
if(my_game.register_capture(card.mob_data))
to_chat(user, "<span class='notice'>Transfer successful!</span>")
qdel(card)
else
to_chat(user, "<span class='warning'>Transfer failed. Could not read mob data from card.</span>")
else
..()
/obj/item/weapon/cartridge/mob_hunt_game/emag_act(mob/user)
if(!emagged)
emagged = 1
var/datum/data/pda/app/mob_hunter_game/my_game = programs[1]
my_game.hacked = 1
to_chat(user, "<span class='warning'>TR4P_M45T3R.mod successfully initialized. ToS violated. User Agreement nullified. Gotta pwn them all.</span>")
to_chat(user, "<span class='warning'>You can now create trapped versions of any mob in your collection that will damage hunters who attempt to capture it.</span>")
description_antag = "This copy of Nano-Mob Hunter GO! has been hacked to allow the creation of trap mobs which will cause any PDA that attempts to capture it to shock anyone holding it. Hacked copies of the game will not trigger the trap."
+182
View File
@@ -0,0 +1,182 @@
/*
This stuff isn't included with in core_apps.dm because it is so distinct and would end up making the file huge (more than it already is).
I put it in it's own file in order to help it stay organized and easier to locate the procs and such.
For reference, the other Nano-mob Hunter GO files are in /code/game/modules/arcade/mob_hunt
*/
/datum/data/pda/app/mob_hunter_game
name = "Nano-Mob Hunter GO"
icon = "gamepad"
template = "pda_mob_hunt"
category = "Games"
var/list/my_collection = list()
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
var/scan_range = 3 //maximum distance (in tiles) from which the client can reveal nearby mobs
/datum/data/pda/app/mob_hunter_game/start()
..()
processing_objects.Add(pda)
/datum/data/pda/app/mob_hunter_game/stop()
..()
disconnect("Program Terminated")
processing_objects.Remove(pda)
/datum/data/pda/app/mob_hunter_game/proc/scan_nearby()
if(!mob_hunt_server || !connected)
return
for(var/turf/T in range(scan_range, get_turf(pda)))
for(var/obj/effect/nanomob/N in T.contents)
if(src in N.clients_encountered)
//hide the mob
N.conceal()
else
//reveal the mob
N.reveal()
/datum/data/pda/app/mob_hunter_game/proc/reconnect()
if(!mob_hunt_server || !mob_hunt_server.server_status || connected)
//show a message about the server being unavailable (because it doesn't exist / didn't get set to the global var / is offline)
return 0
mob_hunt_server.connected_clients += src
connected = 1
if(pda)
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/get_player()
if(!pda)
return null
if(ishuman(pda.loc))
var/mob/living/carbon/human/H = pda.loc
return H
return null
/datum/data/pda/app/mob_hunter_game/proc/disconnect(reason = null)
if(!mob_hunt_server || !connected)
return
mob_hunt_server.connected_clients -= src
for(var/obj/effect/nanomob/N in (mob_hunt_server.normal_spawns + mob_hunt_server.trap_spawns))
N.conceal(list(get_player()))
connected = 0
//show a disconnect message if we were disconnected involuntarily (reason argument provided)
if(pda && 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/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, list/data)
if(!mob_hunt_server || !(src in mob_hunt_server.connected_clients))
data["connected"] = 0
else
data["connected"] = 1
data["wild_captures"] = wild_captures
data["no_collection"] = 0
if(!my_collection.len)
data["no_collection"] = 1
return
var/datum/mob_hunt/mob_info
if(!current_index)
current_index = 1
if(current_index > my_collection.len)
current_index = 1
if(current_index < 1)
current_index = my_collection.len
mob_info = my_collection[current_index]
var/list/entry = list(
"nickname" = mob_info.nickname,
"real_name" = mob_info.mob_name,
"level" = mob_info.level,
"type1" = mob_info.get_type1(),
"type2" = mob_info.get_type2(),
"sprite" = "[mob_info.icon_state_normal].png",
"is_hacked" = hacked
)
if(mob_info.is_shiny)
entry["sprite"] = "[mob_info.icon_state_shiny].png"
data["entry"] = entry
/datum/data/pda/app/mob_hunter_game/proc/assign_nickname()
if(!my_collection.len)
return
var/datum/mob_hunt/mob_info = my_collection[current_index]
var/old_name = mob_info.mob_name
if(mob_info.nickname)
old_name = mob_info.nickname
mob_info.nickname = input("Give a nickname to [old_name]?", "Nickname", old_name)
/datum/data/pda/app/mob_hunter_game/proc/release()
if(!my_collection.len)
return
if(alert("Are you sure you want to release this mob back into the wild?", "Confirm Release", "Yes", "No") == "Yes")
remove_mob()
/datum/data/pda/app/mob_hunter_game/proc/print_card()
if(!pda || !my_collection.len)
return
var/obj/item/weapon/nanomob_card/card = new/obj/item/weapon/nanomob_card(null)
var/datum/mob_hunt/mob_info = my_collection[current_index]
card.mob_data = mob_info
card.update_info()
card.forceMove(get_turf(pda))
remove_mob()
/datum/data/pda/app/mob_hunter_game/proc/remove_mob()
if(!my_collection.len)
return
my_collection.Remove(my_collection[current_index])
if(current_index > my_collection.len)
current_index = my_collection.len
/datum/data/pda/app/mob_hunter_game/proc/set_trap()
if(!my_collection.len || !pda || !hacked)
return
var/datum/mob_hunt/bait = my_collection[current_index]
bait = bait.type
new bait(1, get_turf(pda))
/datum/data/pda/app/mob_hunter_game/Topic(href, list/href_list)
switch(href_list["choice"])
if("Rename")
assign_nickname()
if("Release")
release()
if("Next")
current_index++
if(current_index > my_collection.len)
current_index = 1
if("Prev")
current_index--
if(current_index < 1)
current_index = my_collection.len
if("Reconnect")
reconnect()
if("Disconnect")
disconnect()
if("Transfer")
print_card()
if("Set_Trap")
set_trap()
+6
View File
@@ -57,6 +57,12 @@
typepath = /obj/item/weapon/storage/box/dice
cost = 200
/datum/storeitem/nanomob_booster
name = "Nano-Mob Hunter Trading Card Booster Pack"
desc = "Contains 6 random Nano-Mob Hunter Trading Cards. May contain a holographic card!"
typepath = /obj/item/weapon/storage/box/nanomob_booster_pack
cost = 250
/datum/storeitem/crayons
name = "Crayons"
desc = "Let security know how they're doing by scrawling lovenotes all over their hallways."