Merge pull request #16101 from SandPoot/mech-wars

Mech vs Mech combat system! ... (For toy mechs.)
This commit is contained in:
deathride58
2024-08-25 23:21:05 -04:00
committed by GitHub
30 changed files with 870 additions and 172 deletions

View File

@@ -3166,7 +3166,7 @@
},
/area/awaymission/cabin/caves/sovietcave)
"il" = (
/obj/item/toy/prize/deathripley{
/obj/item/toy/mecha/deathripley{
desc = "The mining mecha of the exploration team.";
name = "exploraton squad Ripley";
pixel_y = 15

View File

@@ -16856,7 +16856,7 @@
/turf/open/floor/plating,
/area/command/heads_quarters/hos)
"aLb" = (
/obj/item/toy/prize/honk,
/obj/item/toy/mecha/honk,
/obj/structure/disposalpipe/segment{
dir = 4
},

View File

@@ -47411,7 +47411,7 @@
"dmL" = (
/obj/machinery/light/small,
/obj/item/toy/dummy,
/obj/item/toy/prize/honk{
/obj/item/toy/mecha/honk{
pixel_y = 12
},
/obj/structure/table/wood,

View File

@@ -17971,7 +17971,7 @@
/area/syndicate_mothership)
"Sb" = (
/obj/structure/table/wood,
/obj/item/toy/prize/mauler{
/obj/item/toy/mecha/mauler{
pixel_y = 12
},
/turf/open/floor/plasteel/dark,

View File

@@ -0,0 +1,35 @@
/**
* ## series element!
*
* bespoke element that assigns a series number to toys on examine, and shows their series name!
* used for mechas and rare collectable hats, should totally be used for way more ;)
*/
/datum/element/series
element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH // Detach for turfs
id_arg_index = 2
var/list/subtype_list
var/series_name
/datum/element/series/Attach(datum/target, subtype, series_name)
. = ..()
if(!isatom(target))
return ELEMENT_INCOMPATIBLE
if(!subtype)
stack_trace("series element without subtype given!")
return ELEMENT_INCOMPATIBLE
subtype_list = subtypesof(subtype)
src.series_name = series_name
var/atom/attached = target
RegisterSignal(attached, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))
/datum/element/series/Detach(datum/target)
. = ..()
UnregisterSignal(target, COMSIG_PARENT_EXAMINE)
///signal called examining
/datum/element/series/proc/on_examine(datum/target, mob/user, list/examine_list)
SIGNAL_HANDLER
var/series_number = subtype_list.Find(target.type)
examine_list += span_boldnotice("[target] is part of the \"[series_name]\" series!")
examine_list += span_notice("Collect them all: [series_number]/[length(subtype_list)].")

View File

@@ -0,0 +1,28 @@
/**
* Allows people to talk via the item with .l or .r
*
* Be sure to override [/atom/movable/proc/GetVoice] if you want the item's "voice" to not default to itself
*/
/datum/element/toy_talk
/datum/element/toy_talk/Attach(datum/target)
. = ..()
if(!isitem(target))
return ELEMENT_INCOMPATIBLE
RegisterSignal(target, COMSIG_ITEM_TALK_INTO, PROC_REF(do_talk))
/datum/element/toy_talk/Detach(datum/source, ...)
. = ..()
UnregisterSignal(source, COMSIG_ITEM_TALK_INTO)
/datum/element/toy_talk/proc/do_talk(obj/item/source, mob/speaker, message, channel, list/spans, language, list/message_mods)
SIGNAL_HANDLER
if(!ismob(speaker) || message_mods[MODE_HEADSET] || message_mods[MODE_RELAY])
return NONE
message_mods[MODE_RELAY] = TRUE // Redundant (given NOPASS) but covers our bases
speaker.log_talk(message, LOG_SAY, tag = "toy talk ([source])")
source.say(message, language = language, sanitize = FALSE, message_mods = list(MODE_RELAY = TRUE))
return NOPASS

View File

@@ -869,7 +869,7 @@
/obj/item/orion_ship
name = "model settler ship"
desc = "A model spaceship, it looks like those used back in the day when travelling to Orion! It even has a miniature FX-293 reactor, which was renowned for its instability and tendency to explode..."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "ship"
w_class = WEIGHT_CLASS_SMALL
var/active = 0 //if the ship is on

View File

@@ -525,7 +525,7 @@ AI MODULES
/obj/item/ai_module/toyAI // -- Incoming //No actual reason to inherit from ion boards here, either. *sigh* ~Miauw
name = "toy AI"
desc = "A little toy model AI core with real law uploading action!" //Note: subtle tell
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "AI"
laws = list("")

View File

@@ -2,7 +2,7 @@
name = "magic eightball"
desc = "A black ball with a stenciled number eight in white on the side. It seems full of dark liquid.\nThe instructions state that you should ask your question aloud, and then shake."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "eightball"
w_class = WEIGHT_CLASS_TINY

View File

@@ -621,7 +621,7 @@
/obj/item/storage/box/snappops
name = "snap pop box"
desc = "Eight wrappers of fun! Ages 8 and up. Not suitable for children."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "spbox"
illustration = null
@@ -870,7 +870,7 @@
/obj/item/storage/box/mechfigures/PopulateContents()
for(var/i in 1 to 4)
var/randomFigure = pick(subtypesof(/obj/item/toy/prize/))
var/randomFigure = pick(subtypesof(/obj/item/toy/mecha))
new randomFigure(src)

View File

@@ -0,0 +1,654 @@
/**
* Mech prizes + MECHA COMBAT!!
*/
/// Mech battle special attack types.
#define SPECIAL_ATTACK_HEAL 1
#define SPECIAL_ATTACK_DAMAGE 2
#define SPECIAL_ATTACK_UTILITY 3
#define SPECIAL_ATTACK_OTHER 4
/// Max length of a mech battle
#define MAX_BATTLE_LENGTH 50
/obj/item/toy/mecha
icon = 'icons/obj/toys/toy.dmi'
icon_state = "fivestarstoy"
verb_say = "beeps"
verb_ask = "beeps"
verb_exclaim = "beeps"
verb_yell = "beeps"
w_class = WEIGHT_CLASS_SMALL
/// Timer when it'll be off cooldown
var/timer = 0
/// Cooldown between play sessions
var/cooldown = 1.5 SECONDS
/// Cooldown multiplier after a battle (by default: battle cooldowns are 30 seconds)
var/cooldown_multiplier = 20
/// If it makes noise when played with
var/quiet = FALSE
/// TRUE = Offering battle to someone || FALSE = Not offering battle
var/wants_to_battle = FALSE
/// TRUE = in combat currently || FALSE = Not in combat
var/in_combat = FALSE
/// The mech's health in battle
var/combat_health = 0
/// The mech's max combat health
var/max_combat_health = 0
/// TRUE = the special attack is charged || FALSE = not charged
var/special_attack_charged = FALSE
/// What type of special attack they use - SPECIAL_ATTACK_DAMAGE, SPECIAL_ATTACK_HEAL, SPECIAL_ATTACK_UTILITY, SPECIAL_ATTACK_OTHER
var/special_attack_type = 0
/// What message their special move gets on examining
var/special_attack_type_message = ""
/// The battlecry when using the special attack
var/special_attack_cry = "*flip"
/// Current cooldown of their special attack
var/special_attack_cooldown = 0
/// This mech's win count in combat
var/wins = 0
/// ...And their loss count in combat
var/losses = 0
/obj/item/toy/mecha/Initialize(mapload)
. = ..()
AddElement(/datum/element/series, /obj/item/toy/mecha, "Mini-Mecha action figures")
//AddElement(/datum/element/toy_talk)
combat_health = max_combat_health
switch(special_attack_type)
if(SPECIAL_ATTACK_DAMAGE)
special_attack_type_message = "an aggressive move, which deals bonus damage."
if(SPECIAL_ATTACK_HEAL)
special_attack_type_message = "a defensive move, which grants bonus healing."
if(SPECIAL_ATTACK_UTILITY)
special_attack_type_message = "a utility move, which heals the user and damages the opponent."
if(SPECIAL_ATTACK_OTHER)
special_attack_type_message = "a special move, which [special_attack_type_message]"
else
special_attack_type_message = "a mystery move, even I don't know."
/**
* this proc combines "sleep" while also checking for if the battle should continue
*
* this goes through some of the checks - the toys need to be next to each other to fight!
* if it's player vs themself: They need to be able to "control" both mechs (either must be adjacent or using TK)
* if it's player vs player: Both players need to be able to "control" their mechs (either must be adjacent or using TK)
* if it's player vs mech (suicide): the mech needs to be in range of the player
* if all the checks are TRUE, it does the sleeps, and returns TRUE. Otherwise, it returns FALSE.
* Arguments:
* * delay - the amount of time the sleep at the end of the check will sleep for
* * attacker - the attacking toy in the battle.
* * attacker_controller - the controller of the attacking toy. there should ALWAYS be an attacker_controller
* * opponent - (optional) the defender controller in the battle, for PvP
*/
/obj/item/toy/mecha/proc/combat_sleep(delay, obj/item/toy/mecha/attacker, mob/living/carbon/attacker_controller, mob/living/carbon/opponent)
if(!attacker_controller)
return FALSE
if(!attacker) //if there's no attacker, then attacker_controller IS the attacker
if(!in_range(src, attacker_controller))
attacker_controller.visible_message(span_suicide("[attacker_controller] is running from [src]! The coward!"))
return FALSE
else // if there's an attacker, we can procede as normal
if(!in_range(src, attacker)) //and the two toys aren't next to each other, the battle ends
attacker_controller.visible_message(span_notice("[attacker] and [src] separate, ending the battle."), \
span_notice("[attacker] and [src] separate, ending the battle."))
return FALSE
//dead men tell no tales, incapacitated men fight no fights
if(attacker_controller.incapacitated())
return FALSE
//if the attacker_controller isn't next to the attacking toy (and doesn't have telekinesis), the battle ends
if(!in_range(attacker, attacker_controller) && !(attacker_controller.dna.check_mutation(/datum/mutation/human/telekinesis)))
attacker_controller.visible_message(span_notice("[attacker_controller.name] separates from [attacker], ending the battle."), \
span_notice("You separate from [attacker], ending the battle."))
return FALSE
//if it's PVP and the opponent is not next to the defending(src) toy (and doesn't have telekinesis), the battle ends
if(opponent)
if(opponent.incapacitated())
return FALSE
if(!in_range(src, opponent) && !(opponent.dna.check_mutation(/datum/mutation/human/telekinesis)))
opponent.visible_message(span_notice("[opponent.name] separates from [src], ending the battle."), \
span_notice("You separate from [src], ending the battle."))
return FALSE
//if it's not PVP and the attacker_controller isn't next to the defending toy (and doesn't have telekinesis), the battle ends
else
if (!in_range(src, attacker_controller) && !(attacker_controller.dna.check_mutation(/datum/mutation/human/telekinesis)))
attacker_controller.visible_message(span_notice("[attacker_controller.name] separates from [src] and [attacker], ending the battle."), \
span_notice("You separate [attacker] and [src], ending the battle."))
return FALSE
//if all that is good, then we can sleep peacefully
sleep(delay)
return TRUE
//all credit to skasi for toy mech fun ideas
/obj/item/toy/mecha/attack_self(mob/user)
if(timer < world.time)
to_chat(user, span_notice("You play with [src]."))
timer = world.time + cooldown
if(!quiet)
playsound(user, 'sound/mecha/mechstep.ogg', 20, TRUE)
else
. = ..()
/obj/item/toy/mecha/attack_hand(mob/user, list/modifiers)
. = ..()
if(.)
return
if(loc == user)
attack_self(user)
/**
* If you attack a mech with a mech, initiate combat between them
*/
/obj/item/toy/mecha/attackby(obj/item/user_toy, mob/living/user)
if(istype(user_toy, /obj/item/toy/mecha))
var/obj/item/toy/mecha/P = user_toy
if(check_battle_start(user, P))
mecha_brawl(P, user)
..()
/**
* Attack is called from the user's toy, aimed at target(another human), checking for target's toy.
*/
/obj/item/toy/mecha/attack(mob/living/carbon/human/target, mob/living/carbon/human/user)
if(target == user)
to_chat(user, span_notice("Target another toy mech if you want to start a battle with yourself."))
return
else if(user.a_intent != INTENT_HARM)
if(wants_to_battle) //prevent spamming someone with offers
to_chat(user, span_notice("You already are offering battle to someone!"))
return
if(!check_battle_start(user)) //if the user's mech isn't ready, don't bother checking
return
for(var/obj/item/I in target.held_items)
if(istype(I, /obj/item/toy/mecha)) //if you attack someone with a mech who's also holding a mech, offer to battle them
var/obj/item/toy/mecha/P = I
if(!P.check_battle_start(target, null, user)) //check if the attacker mech is ready
break
//slap them with the metaphorical white glove
if(P.wants_to_battle) //if the target mech wants to battle, initiate the battle from their POV
mecha_brawl(P, target, user) //P = defender's mech / SRC = attacker's mech / target = defender / user = attacker
P.wants_to_battle = FALSE
return
//extend the offer of battle to the other mech
to_chat(user, span_notice("You offer battle to [target.name]!"))
to_chat(target, span_notice("<b>[user.name] wants to battle with [user.p_their()] [name]!</b> <i>Attack them with a toy mech to initiate combat.</i>"))
wants_to_battle = TRUE
addtimer(CALLBACK(src, PROC_REF(withdraw_offer), user), 6 SECONDS)
return
..()
/**
* Overrides attack_tk - Sorry, you have to be face to face to initiate a battle, it's good sportsmanship
*/
/obj/item/toy/mecha/attack_tk(mob/user)
if(timer < world.time)
to_chat(user, span_notice("You telekinetically play with [src]."))
timer = world.time + cooldown
if(!quiet)
playsound(user, 'sound/mecha/mechstep.ogg', 20, TRUE)
return STOP_ATTACK_PROC_CHAIN
/**
* Resets the request for battle.
*
* For use in a timer, this proc resets the wants_to_battle variable after a short period.
* Arguments:
* * user - the user wanting to do battle
*/
/obj/item/toy/mecha/proc/withdraw_offer(mob/living/carbon/user)
if(wants_to_battle)
wants_to_battle = FALSE
to_chat(user, span_notice("You get the feeling they don't want to battle."))
/**
* Starts a battle, toy mech vs player. Player... doesn't win.
*/
/obj/item/toy/mecha/suicide_act(mob/living/carbon/user)
if(in_combat)
to_chat(user, span_notice("[src] is in battle, let it finish first."))
return
user.visible_message(span_suicide("[user] begins a fight [user.p_they()] can't win with [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
in_combat = TRUE
sleep(1.5 SECONDS)
for(var/i in 1 to 4)
switch(i)
if(1, 3)
SpinAnimation(5, 0)
playsound(src, 'sound/mecha/mechstep.ogg', 30, TRUE)
user.adjustBruteLoss(25)
user.adjustStaminaLoss(50)
if(2)
user.SpinAnimation(5, 0)
playsound(user, 'sound/weapons/smash.ogg', 20, TRUE)
combat_health-- //we scratched it!
if(4)
say(special_attack_cry + "!!")
user.adjustStaminaLoss(25)
if(!combat_sleep(1 SECONDS, null, user))
say("PATHETIC.")
combat_health = max_combat_health
in_combat = FALSE
return SHAME
sleep(0.5 SECONDS)
user.adjustBruteLoss(450)
in_combat = FALSE
say("AN EASY WIN. MY POWER INCREASES.") // steal a soul, become swole
add_atom_colour(rgb(255, 115, 115), ADMIN_COLOUR_PRIORITY)
max_combat_health = round(max_combat_health*1.5 + 0.1)
combat_health = max_combat_health
wins++
return BRUTELOSS
/obj/item/toy/mecha/examine()
. = ..()
. += span_notice("This toy's special attack is [special_attack_cry], [special_attack_type_message]")
if(in_combat)
. += span_notice("This toy has a maximum health of [max_combat_health]. Currently, it's [combat_health].")
. += span_notice("Its special move light is [special_attack_cooldown? "flashing red." : "green and is ready!"]")
else
. += span_notice("This toy has a maximum health of [max_combat_health].")
if(wins || losses)
. += span_notice("This toy has [wins] wins, and [losses] losses.")
/obj/item/toy/mecha/can_speak(allow_mimes)
return !quiet && ..()
/**
* The 'master' proc of the mech battle. Processes the entire battle's events and makes sure it start and finishes correctly.
*
* src is the defending toy, and the battle proc is called on it to begin the battle.
* After going through a few checks at the beginning to ensure the battle can start properly, the battle begins a loop that lasts
* until either toy has no more health. During this loop, it also ensures the mechs stay in combat range of each other.
* It will then randomly decide attacks for each toy, occasionally making one or the other use their special attack.
* When either mech has no more health, the loop ends, and it displays the victor and the loser while updating their stats and resetting them.
* Arguments:
* * attacker - the attacking toy, the toy in the attacker_controller's hands
* * attacker_controller - the user, the one who is holding the toys / controlling the fight
* * opponent - optional arg used in Mech PvP battles: the other person who is taking part in the fight (controls src)
*/
/obj/item/toy/mecha/proc/mecha_brawl(obj/item/toy/mecha/attacker, mob/living/carbon/attacker_controller, mob/living/carbon/opponent)
//A GOOD DAY FOR A SWELL BATTLE!
attacker_controller.visible_message(span_danger("[attacker_controller.name] collides [attacker] with [src]! Looks like they're preparing for a brawl!"), \
span_danger("You collide [attacker] into [src], sparking a fierce battle!"), \
span_hear("You hear hard plastic smacking into hard plastic."), COMBAT_MESSAGE_RANGE)
/// Who's in control of the defender (src)?
var/mob/living/carbon/src_controller = (opponent)? opponent : attacker_controller
/// How long has the battle been going?
var/battle_length = 0
in_combat = TRUE
attacker.in_combat = TRUE
//1.5 second cooldown * 20 = 30 second cooldown after a fight
timer = world.time + cooldown*cooldown_multiplier
attacker.timer = world.time + attacker.cooldown*attacker.cooldown_multiplier
sleep(1 SECONDS)
//--THE BATTLE BEGINS--
while(combat_health > 0 && attacker.combat_health > 0 && battle_length < MAX_BATTLE_LENGTH)
if(!combat_sleep(0.5 SECONDS, attacker, attacker_controller, opponent)) //combat_sleep checks everything we need to have checked for combat to continue
break
//before we do anything - deal with charged attacks
if(special_attack_charged)
src_controller.visible_message(span_danger("[src] unleashes its special attack!!"), \
span_danger("You unleash [src]'s special attack!"))
special_attack_move(attacker)
else if(attacker.special_attack_charged)
attacker_controller.visible_message(span_danger("[attacker] unleashes its special attack!!"), \
span_danger("You unleash [attacker]'s special attack!"))
attacker.special_attack_move(src)
else
//process the cooldowns
if(special_attack_cooldown > 0)
special_attack_cooldown--
if(attacker.special_attack_cooldown > 0)
attacker.special_attack_cooldown--
//combat commences
switch(rand(1,8))
if(1 to 3) //attacker wins
if(attacker.special_attack_cooldown == 0 && attacker.combat_health <= round(attacker.max_combat_health/3)) //if health is less than 1/3 and special off CD, use it
attacker.special_attack_charged = TRUE
attacker_controller.visible_message(span_danger("[attacker] begins charging its special attack!!"), \
span_danger("You begin charging [attacker]'s special attack!"))
else //just attack
attacker.SpinAnimation(5, 0)
playsound(attacker, 'sound/mecha/mechstep.ogg', 30, TRUE)
combat_health--
attacker_controller.visible_message(span_danger("[attacker] devastates [src]!"), \
span_danger("You ram [attacker] into [src]!"), \
span_hear("You hear hard plastic smacking hard plastic."), COMBAT_MESSAGE_RANGE)
if(prob(5))
combat_health--
playsound(src, 'sound/effects/meteorimpact.ogg', 20, TRUE)
attacker_controller.visible_message(span_boldwarning("...and lands a CRIPPLING BLOW!"), \
span_boldwarning("...and you land a CRIPPLING blow on [src]!"), null, COMBAT_MESSAGE_RANGE)
if(4) //both lose
attacker.SpinAnimation(5, 0)
SpinAnimation(5, 0)
combat_health--
attacker.combat_health--
do_sparks(2, FALSE, src)
do_sparks(2, FALSE, attacker)
if(prob(50))
attacker_controller.visible_message(span_danger("[attacker] and [src] clash dramatically, causing sparks to fly!"), \
span_danger("[attacker] and [src] clash dramatically, causing sparks to fly!"), \
span_hear("You hear hard plastic rubbing against hard plastic."), COMBAT_MESSAGE_RANGE)
else
src_controller.visible_message(span_danger("[src] and [attacker] clash dramatically, causing sparks to fly!"), \
span_danger("[src] and [attacker] clash dramatically, causing sparks to fly!"), \
span_hear("You hear hard plastic rubbing against hard plastic."), COMBAT_MESSAGE_RANGE)
if(5) //both win
playsound(attacker, 'sound/weapons/parry.ogg', 20, TRUE)
if(prob(50))
attacker_controller.visible_message(span_danger("[src]'s attack deflects off of [attacker]."), \
span_danger("[src]'s attack deflects off of [attacker]."), \
span_hear("You hear hard plastic bouncing off hard plastic."), COMBAT_MESSAGE_RANGE)
else
src_controller.visible_message(span_danger("[attacker]'s attack deflects off of [src]."), \
span_danger("[attacker]'s attack deflects off of [src]."), \
span_hear("You hear hard plastic bouncing off hard plastic."), COMBAT_MESSAGE_RANGE)
if(6 to 8) //defender wins
if(special_attack_cooldown == 0 && combat_health <= round(max_combat_health/3)) //if health is less than 1/3 and special off CD, use it
special_attack_charged = TRUE
src_controller.visible_message(span_danger("[src] begins charging its special attack!!"), \
span_danger("You begin charging [src]'s special attack!"))
else //just attack
SpinAnimation(5, 0)
playsound(src, 'sound/mecha/mechstep.ogg', 30, TRUE)
attacker.combat_health--
src_controller.visible_message(span_danger("[src] smashes [attacker]!"), \
span_danger("You smash [src] into [attacker]!"), \
span_hear("You hear hard plastic smashing hard plastic."), COMBAT_MESSAGE_RANGE)
if(prob(5))
attacker.combat_health--
playsound(attacker, 'sound/effects/meteorimpact.ogg', 20, TRUE)
src_controller.visible_message(span_boldwarning("...and lands a CRIPPLING BLOW!"), \
span_boldwarning("...and you land a CRIPPLING blow on [attacker]!"), null, COMBAT_MESSAGE_RANGE)
else
attacker_controller.visible_message(span_notice("[src] and [attacker] stand around awkwardly."), \
span_notice("You don't know what to do next."))
battle_length++
sleep(0.5 SECONDS)
/// Lines chosen for the winning mech
var/list/winlines = list("YOU'RE NOTHING BUT SCRAP!", "I'LL YIELD TO NONE!", "GLORY IS MINE!", "AN EASY FIGHT.", "YOU SHOULD HAVE NEVER FACED ME.", "ROCKED AND SOCKED.")
if(attacker.combat_health <= 0 && combat_health <= 0) //both lose
playsound(src, 'sound/machines/warning-buzzer.ogg', 20, TRUE)
attacker_controller.visible_message(span_boldnotice("MUTUALLY ASSURED DESTRUCTION!! [src] and [attacker] both end up destroyed!"), \
span_boldnotice("Both [src] and [attacker] are destroyed!"))
else if(attacker.combat_health <= 0) //src wins
wins++
attacker.losses++
playsound(attacker, 'sound/effects/light_flicker.ogg', 20, TRUE)
attacker_controller.visible_message(span_notice("[attacker] falls apart!"), \
span_notice("[attacker] falls apart!"), null, COMBAT_MESSAGE_RANGE)
say("[pick(winlines)]")
src_controller.visible_message(span_notice("[src] destroys [attacker] and walks away victorious!"), \
span_notice("You raise up [src] victoriously over [attacker]!"))
else if (combat_health <= 0) //attacker wins
attacker.wins++
losses++
playsound(src, 'sound/effects/light_flicker.ogg', 20, TRUE)
src_controller.visible_message(span_notice("[src] collapses!"), \
span_notice("[src] collapses!"), null, COMBAT_MESSAGE_RANGE)
attacker.say("[pick(winlines)]")
attacker_controller.visible_message(span_notice("[attacker] demolishes [src] and walks away victorious!"), \
"[span_notice("You raise up [attacker] proudly over [src]")]!")
else //both win?
say("NEXT TIME.")
//don't want to make this a one sided conversation
quiet? attacker.say("I WENT EASY ON YOU.") : attacker.say("OF COURSE.")
in_combat = FALSE
attacker.in_combat = FALSE
combat_health = max_combat_health
attacker.combat_health = attacker.max_combat_health
return
/**
* This proc checks if a battle can be initiated between src and attacker.
*
* Both SRC and attacker (if attacker is included) timers are checked if they're on cooldown, and
* both SRC and attacker (if attacker is included) are checked if they are in combat already.
* If any of the above are true, the proc returns FALSE and sends a message to user (and target, if included) otherwise, it returns TRUE
* Arguments:
* * user: the user who is initiating the battle
* * attacker: optional arg for checking two mechs at once
* * target: optional arg used in Mech PvP battles (if used, attacker is target's toy)
*/
/obj/item/toy/mecha/proc/check_battle_start(mob/living/carbon/user, obj/item/toy/mecha/attacker, mob/living/carbon/target)
if(attacker?.in_combat)
to_chat(user, span_notice("[target?target.p_their() : "Your" ] [attacker.name] is in combat."))
to_chat(target, span_notice("Your [attacker.name] is in combat."))
return FALSE
if(in_combat)
to_chat(user, span_notice("Your [name] is in combat."))
to_chat(target, span_notice("[user.p_their()] [name] is in combat."))
return FALSE
if(attacker && attacker.timer > world.time)
to_chat(user, span_notice("[target?target.p_their() : "Your" ] [attacker.name] isn't ready for battle."))
to_chat(target, span_notice("Your [attacker.name] isn't ready for battle."))
return FALSE
if(timer > world.time)
to_chat(user, span_notice("Your [name] isn't ready for battle."))
to_chat(target, span_notice("[user.p_their()] [name] isn't ready for battle."))
return FALSE
return TRUE
/**
* Processes any special attack moves that happen in the battle (called in the mechaBattle proc).
*
* Makes the toy shout their special attack cry and updates its cooldown. Then, does the special attack.
* Arguments:
* * victim - the toy being hit by the special move
*/
/obj/item/toy/mecha/proc/special_attack_move(obj/item/toy/mecha/victim)
say(special_attack_cry + "!!")
special_attack_charged = FALSE
special_attack_cooldown = 3
switch(special_attack_type)
if(SPECIAL_ATTACK_DAMAGE) //+2 damage
victim.combat_health-=2
playsound(src, 'sound/weapons/marauder.ogg', 20, TRUE)
if(SPECIAL_ATTACK_HEAL) //+2 healing
combat_health+=2
playsound(src, 'sound/mecha/mech_shield_raise.ogg', 20, TRUE)
if(SPECIAL_ATTACK_UTILITY) //+1 heal, +1 damage
victim.combat_health--
combat_health++
playsound(src, 'sound/mecha/mechmove01.ogg', 30, TRUE)
if(SPECIAL_ATTACK_OTHER) //other
super_special_attack(victim)
else
say("I FORGOT MY SPECIAL ATTACK...")
/**
* Base proc for 'other' special attack moves.
*
* This one is only for inheritance, each mech with an 'other' type move has their procs below.
* Arguments:
* * victim - the toy being hit by the super special move (doesn't necessarily need to be used)
*/
/obj/item/toy/mecha/proc/super_special_attack(obj/item/toy/mecha/victim)
visible_message(span_notice("[src] does a cool flip."))
/obj/item/toy/mecha/ripley
name = "toy Ripley MK-I"
icon_state = "ripleytoy"
max_combat_health = 4 //200 integrity
special_attack_type = SPECIAL_ATTACK_DAMAGE
special_attack_cry = "CLAMP SMASH"
/obj/item/toy/mecha/ripleymkii
name = "toy Ripley MK-II"
icon_state = "ripleymkiitoy"
max_combat_health = 5 //250 integrity
special_attack_type = SPECIAL_ATTACK_DAMAGE
special_attack_cry = "GIGA DRILL BREAK"
/obj/item/toy/mecha/hauler
name = "toy Hauler"
icon_state = "haulertoy"
max_combat_health = 3 //100 integrity?
special_attack_type = SPECIAL_ATTACK_UTILITY
special_attack_cry = "HAUL AWAY"
/obj/item/toy/mecha/clarke
name = "toy Clarke"
icon_state = "clarketoy"
max_combat_health = 4 //200 integrity
special_attack_type = SPECIAL_ATTACK_UTILITY
special_attack_cry = "ROLL OUT"
/obj/item/toy/mecha/odysseus
name = "toy Odysseus"
icon_state = "odysseustoy"
max_combat_health = 4 //120 integrity
special_attack_type = SPECIAL_ATTACK_HEAL
special_attack_cry = "MECHA BEAM"
/obj/item/toy/mecha/gygax
name = "toy Gygax"
icon_state = "gygaxtoy"
max_combat_health = 5 //250 integrity
special_attack_type = SPECIAL_ATTACK_UTILITY
special_attack_cry = "SUPER SERVOS"
/obj/item/toy/mecha/durand
name = "toy Durand"
icon_state = "durandtoy"
max_combat_health = 6 //400 integrity
special_attack_type = SPECIAL_ATTACK_HEAL
special_attack_cry = "SHIELD OF PROTECTION"
/obj/item/toy/mecha/savannahivanov
name = "toy Savannah-Ivanov"
icon_state = "savannahivanovtoy"
max_combat_health = 7 //450 integrity
special_attack_type = SPECIAL_ATTACK_UTILITY
special_attack_cry = "SKYFALL!! IVANOV STRIKE"
/obj/item/toy/mecha/phazon
name = "toy Phazon"
icon_state = "phazontoy"
max_combat_health = 6 //200 integrity
special_attack_type = SPECIAL_ATTACK_UTILITY
special_attack_cry = "NO-CLIP"
/obj/item/toy/mecha/honk
name = "toy H.O.N.K."
icon_state = "honktoy"
max_combat_health = 4 //140 integrity
special_attack_type = SPECIAL_ATTACK_OTHER
special_attack_type_message = "puts the opposing mech's special move on cooldown and heals this mech."
special_attack_cry = "MEGA HORN"
/obj/item/toy/mecha/honk/super_special_attack(obj/item/toy/mecha/victim)
playsound(src, 'sound/machines/honkbot_evil_laugh.ogg', 20, TRUE)
victim.special_attack_cooldown += 3 //Adds cooldown to the other mech and gives a minor self heal
combat_health++
/obj/item/toy/mecha/darkgygax
name = "toy Dark Gygax"
icon_state = "darkgygaxtoy"
max_combat_health = 6 //300 integrity
special_attack_type = SPECIAL_ATTACK_UTILITY
special_attack_cry = "ULTRA SERVOS"
/obj/item/toy/mecha/mauler
name = "toy Mauler"
icon_state = "maulertoy"
max_combat_health = 7 //500 integrity
special_attack_type = SPECIAL_ATTACK_DAMAGE
special_attack_cry = "BULLET STORM"
/obj/item/toy/mecha/darkhonk
name = "toy Dark H.O.N.K."
icon_state = "darkhonktoy"
max_combat_health = 5 //300 integrity
special_attack_type = SPECIAL_ATTACK_DAMAGE
special_attack_cry = "BOMBANANA SPREE"
/obj/item/toy/mecha/deathripley
name = "toy Death-Ripley"
icon_state = "deathripleytoy"
max_combat_health = 5 //250 integrity
special_attack_type = SPECIAL_ATTACK_OTHER
special_attack_type_message = "instantly destroys the opposing mech if its health is less than this mech's health."
special_attack_cry = "KILLER CLAMP"
/obj/item/toy/mecha/deathripley/super_special_attack(obj/item/toy/mecha/victim)
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 20, TRUE)
if(victim.combat_health < combat_health) //Instantly kills the other mech if it's health is below our's.
say("EXECUTE!!")
victim.combat_health = 0
else //Otherwise, just deal one damage.
victim.combat_health--
/obj/item/toy/mecha/reticence
name = "toy Reticence"
icon_state = "reticencetoy"
quiet = TRUE
max_combat_health = 4 //100 integrity
special_attack_type = SPECIAL_ATTACK_OTHER
special_attack_type_message = "has a lower cooldown than normal special moves, increases the opponent's cooldown, and deals damage."
special_attack_cry = "*wave"
/obj/item/toy/mecha/reticence/super_special_attack(obj/item/toy/mecha/victim)
special_attack_cooldown-- //Has a lower cooldown...
victim.special_attack_cooldown++ //and increases the opponent's cooldown by 1...
victim.combat_health-- //and some free damage.
/obj/item/toy/mecha/marauder
name = "toy Marauder"
icon_state = "maraudertoy"
max_combat_health = 7 //500 integrity
special_attack_type = SPECIAL_ATTACK_DAMAGE
special_attack_cry = "BEAM BLAST"
/obj/item/toy/mecha/seraph
name = "toy Seraph"
icon_state = "seraphtoy"
max_combat_health = 8 //550 integrity
special_attack_type = SPECIAL_ATTACK_DAMAGE
special_attack_cry = "ROCKET BARRAGE"
/obj/item/toy/mecha/firefighter //rip
name = "toy Firefighter"
icon_state = "firefightertoy"
max_combat_health = 5 //250 integrity?
special_attack_type = SPECIAL_ATTACK_HEAL
special_attack_cry = "FIRE SHIELD"
#undef SPECIAL_ATTACK_HEAL
#undef SPECIAL_ATTACK_DAMAGE
#undef SPECIAL_ATTACK_UTILITY
#undef SPECIAL_ATTACK_OTHER
#undef MAX_BATTLE_LENGTH

View File

@@ -7,7 +7,6 @@
* Toy swords
* Crayons
* Snap pops
* Mech prizes
* AI core prizes
* Toy codex gigas
* Skeleton toys
@@ -24,7 +23,6 @@
* Toy Daggers
*/
/obj/item/toy
throwforce = 0
throw_speed = 3
@@ -39,7 +37,7 @@
/obj/item/toy/balloon
name = "water balloon"
desc = "A translucent balloon. There's nothing in it."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "waterballoon-e"
item_state = "balloon-empty"
@@ -379,7 +377,7 @@
/obj/item/toy/foamblade
name = "foam armblade"
desc = "It says \"Sternside Changs #1 fan\" on it."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "foamblade"
item_state = "arm_blade"
lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi'
@@ -508,7 +506,7 @@
/obj/item/toy/snappop
name = "snap pop"
desc = "Wow!"
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "snappop"
w_class = WEIGHT_CLASS_TINY
var/ash_type = /obj/effect/decal/cleanable/ash
@@ -544,7 +542,7 @@
ash_type = /obj/effect/decal/cleanable/ash/snappop_phoenix
/obj/effect/decal/cleanable/ash/snappop_phoenix
var/respawn_time = 300
var/respawn_time = 30 SECONDS
/obj/effect/decal/cleanable/ash/snappop_phoenix/New()
. = ..()
@@ -554,96 +552,10 @@
new /obj/item/toy/snappop/phoenix(get_turf(src))
qdel(src)
/*
* Mech prizes
*/
/obj/item/toy/prize
icon = 'icons/obj/toy.dmi'
icon_state = "ripleytoy"
var/timer = 0
var/cooldown = 30
var/quiet = 0
//all credit to skasi for toy mech fun ideas
/obj/item/toy/prize/attack_self(mob/user)
if(timer < world.time)
to_chat(user, "<span class='notice'>You play with [src].</span>")
timer = world.time + cooldown
if(!quiet)
playsound(user, 'sound/mecha/mechstep.ogg', 20, 1)
else
. = ..()
/obj/item/toy/prize/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(loc == user)
attack_self(user)
/obj/item/toy/prize/ripley
name = "toy Ripley"
desc = "Mini-Mecha action figure! Collect them all! 1/12."
/obj/item/toy/prize/fireripley
name = "toy firefighting Ripley"
desc = "Mini-Mecha action figure! Collect them all! 2/12."
icon_state = "fireripleytoy"
/obj/item/toy/prize/deathripley
name = "toy deathsquad Ripley"
desc = "Mini-Mecha action figure! Collect them all! 3/12."
icon_state = "deathripleytoy"
/obj/item/toy/prize/gygax
name = "toy Gygax"
desc = "Mini-Mecha action figure! Collect them all! 4/12."
icon_state = "gygaxtoy"
/obj/item/toy/prize/durand
name = "toy Durand"
desc = "Mini-Mecha action figure! Collect them all! 5/12."
icon_state = "durandprize"
/obj/item/toy/prize/honk
name = "toy H.O.N.K."
desc = "Mini-Mecha action figure! Collect them all! 6/12."
icon_state = "honkprize"
/obj/item/toy/prize/marauder
name = "toy Marauder"
desc = "Mini-Mecha action figure! Collect them all! 7/12."
icon_state = "marauderprize"
/obj/item/toy/prize/seraph
name = "toy Seraph"
desc = "Mini-Mecha action figure! Collect them all! 8/12."
icon_state = "seraphprize"
/obj/item/toy/prize/mauler
name = "toy Mauler"
desc = "Mini-Mecha action figure! Collect them all! 9/12."
icon_state = "maulerprize"
/obj/item/toy/prize/odysseus
name = "toy Odysseus"
desc = "Mini-Mecha action figure! Collect them all! 10/12."
icon_state = "odysseusprize"
/obj/item/toy/prize/phazon
name = "toy Phazon"
desc = "Mini-Mecha action figure! Collect them all! 11/12."
icon_state = "phazonprize"
/obj/item/toy/prize/reticence
name = "toy Reticence"
desc = "Mini-Mecha action figure! Collect them all! 12/12."
icon_state = "reticenceprize"
quiet = 1
/obj/item/toy/talking
name = "talking action figure"
desc = "A generic action figure modeled after nothing in particular."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "owlprize"
w_class = WEIGHT_CLASS_SMALL
var/cooldown = FALSE
@@ -772,7 +684,7 @@
/obj/item/toy/cards/deck
name = "deck of cards"
desc = "A deck of space-grade playing cards."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
deckstyle = "nanotrasen"
icon_state = "deck_nanotrasen_full"
w_class = WEIGHT_CLASS_SMALL
@@ -903,7 +815,7 @@
/obj/item/toy/cards/cardhand
name = "hand of cards"
desc = "A number of cards not in a deck, customarily held in ones hand."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "none"
w_class = WEIGHT_CLASS_TINY
var/list/currenthand = list()
@@ -1000,7 +912,7 @@
/obj/item/toy/cards/singlecard
name = "card"
desc = "a card"
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "singlecard_down_nanotrasen"
w_class = WEIGHT_CLASS_TINY
var/cardname = null
@@ -1124,7 +1036,7 @@
/obj/item/toy/nuke
name = "\improper Nuclear Fission Explosive toy"
desc = "A plastic model of a Nuclear Fission Explosive."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "nuketoyidle"
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
@@ -1151,7 +1063,7 @@
/obj/item/toy/minimeteor
name = "\improper Mini-Meteor"
desc = "Relive the excitement of a meteor shower! SweetMeat-eor. Co is not responsible for any injuries, headaches or hearing loss caused by Mini-Meteor."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "minimeteor"
w_class = WEIGHT_CLASS_SMALL
@@ -1194,7 +1106,7 @@
/obj/item/toy/snowball
name = "snowball"
desc = "A compact ball of snow. Good for throwing at people."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "snowball"
throwforce = 12 //pelt your enemies to death with lumps of snow
damtype = STAMINA
@@ -1268,7 +1180,7 @@
*/
/obj/item/toy/toy_xeno
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "toy_xeno"
name = "xenomorph action figure"
desc = "MEGA presents the new Xenos Isolated action figure! Comes complete with realistic sounds! Pull back string to use."
@@ -1297,7 +1209,7 @@
/obj/item/toy/cattoy
name = "toy mouse"
desc = "A colorful toy mouse!"
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "toy_mouse"
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
@@ -1311,7 +1223,7 @@
/obj/item/toy/figure
name = "Non-Specific Action Figure action figure"
desc = null
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "nuketoy"
var/cooldown = 0
var/toysay = "What the fuck did you do?"
@@ -1518,7 +1430,7 @@
/obj/item/toy/dummy
name = "ventriloquist dummy"
desc = "It's a dummy, dummy."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "assistant"
item_state = "doll"
var/doll_name = "Dummy"

View File

@@ -150,24 +150,30 @@
/obj/item/toy/talking/AI,
/obj/item/toy/talking/codex_gigas,
/obj/item/clothing/under/syndicate/tacticool,
/obj/item/toy/sword ,
/obj/item/toy/sword,
/obj/item/toy/gun,
/obj/item/gun/ballistic/shotgun/toy/crossbow,
/obj/item/storage/box/fakesyndiesuit,
/obj/item/storage/crayons,
/obj/item/toy/spinningtoy,
/obj/item/toy/prize/ripley,
/obj/item/toy/prize/fireripley,
/obj/item/toy/prize/deathripley,
/obj/item/toy/prize/gygax,
/obj/item/toy/prize/durand,
/obj/item/toy/prize/honk,
/obj/item/toy/prize/marauder,
/obj/item/toy/prize/seraph,
/obj/item/toy/prize/mauler,
/obj/item/toy/prize/odysseus,
/obj/item/toy/prize/phazon,
/obj/item/toy/prize/reticence,
/obj/item/toy/mecha/ripley,
/obj/item/toy/mecha/ripleymkii,
/obj/item/toy/mecha/hauler,
/obj/item/toy/mecha/clarke,
/obj/item/toy/mecha/odysseus,
/obj/item/toy/mecha/gygax,
/obj/item/toy/mecha/durand,
/obj/item/toy/mecha/savannahivanov,
/obj/item/toy/mecha/phazon,
/obj/item/toy/mecha/honk,
/obj/item/toy/mecha/darkgygax,
/obj/item/toy/mecha/mauler,
/obj/item/toy/mecha/darkhonk,
/obj/item/toy/mecha/deathripley,
/obj/item/toy/mecha/reticence,
/obj/item/toy/mecha/marauder,
/obj/item/toy/mecha/seraph,
/obj/item/toy/mecha/firefighter,
/obj/item/toy/cards/deck,
/obj/item/toy/nuke,
/obj/item/toy/minimeteor,

View File

@@ -4,6 +4,11 @@
/obj/item/clothing/head/collectable
name = "collectable hat"
desc = "A rare collectable hat."
icon_state = null
/obj/item/clothing/head/collectable/Initialize()
. = ..()
AddElement(/datum/element/series, /obj/item/clothing/head/collectable, "Super duper collectable hats")
/obj/item/clothing/head/collectable/petehat
name = "ultra rare Pete's hat!"

View File

@@ -40,7 +40,7 @@
/obj/item/valentine
name = "valentine"
desc = "A Valentine's card! Wonder what it says..."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "sc_Ace of Hearts_syndicate" // shut up
var/message = "A generic message of love or whatever."
resistance_flags = FLAMMABLE

View File

@@ -12,7 +12,7 @@
/obj/item/toy/cards/deck/cas
name = "\improper CAS deck (white)"
desc = "A deck for the game Cards Against Spess, still popular after all these centuries. Warning: may include traces of broken fourth wall. This is the white deck."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "deck_caswhite_full"
deckstyle = "caswhite"
var/card_face = "cas_white"

View File

@@ -2,7 +2,7 @@
/obj/item/toy/cards/deck/unum
name = "\improper UNUM deck"
desc = "A deck of unum cards. House rules to argue over not included."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "deck_unum_full"
deckstyle = "unum"
original_size = 108

View File

@@ -118,7 +118,7 @@
var/eggcolor = pick("blue","green","mime","orange","purple","rainbow","red","yellow")
icon_state = "egg-[eggcolor]"
/obj/item/reagent_containers/food/snacks/egg/proc/dispensePrize(turf/where)
var/won = pick(/obj/item/clothing/head/bunnyhead,
var/prize_list = list(/obj/item/clothing/head/bunnyhead,
/obj/item/clothing/suit/bunnysuit,
/obj/item/reagent_containers/food/snacks/grown/carrot,
/obj/item/reagent_containers/food/snacks/chocolateegg,
@@ -126,13 +126,12 @@
/obj/item/toy/gun,
/obj/item/toy/sword,
/obj/item/toy/foamblade,
/obj/item/toy/prize/ripley,
/obj/item/toy/prize/honk,
/obj/item/toy/plush/carpplushie,
/obj/item/toy/redbutton,
/obj/item/clothing/head/collectable/rabbitears)
/obj/item/clothing/head/collectable/rabbitears) + subtypesof(/obj/item/toy/mecha)
var/won = pick(prize_list)
new won(where)
new/obj/item/reagent_containers/food/snacks/chocolateegg(where)
new /obj/item/reagent_containers/food/snacks/chocolateegg(where)
/obj/item/reagent_containers/food/snacks/egg/attack_self(mob/user)
..()

View File

@@ -26,7 +26,7 @@
// Generates a holodeck-tracked card deck
/obj/effect/holodeck_effect/cards
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "deck_nanotrasen_full"
var/obj/item/toy/cards/deck/D

View File

@@ -27,7 +27,7 @@
threat = 1
family_heirlooms = list(
/obj/item/toy/figure/borg
/obj/item/toy/figure/borg,
)
mail_goodies = list(
@@ -36,6 +36,10 @@
/obj/item/modular_computer/tablet/preset/advanced = 5
)
/datum/job/roboticist/New()
. = ..()
family_heirlooms += subtypesof(/obj/item/toy/mecha)
/datum/outfit/job/roboticist
name = "Roboticist"
jobtype = /datum/job/roboticist

View File

@@ -61,7 +61,7 @@
if(53 to 54)
new /obj/item/toy/balloon(src)
if(55 to 56)
var/newitem = pick(subtypesof(/obj/item/toy/prize))
var/newitem = pick(subtypesof(/obj/item/toy/mecha))
new newitem(src)
if(57 to 58)
new /obj/item/toy/syndicateballoon(src)

View File

@@ -512,7 +512,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
/obj/item/guardiancreator
name = "deck of tarot cards"
desc = "An enchanted deck of tarot cards, rumored to be a source of unimaginable power."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "deck_syndicate_full"
var/used = FALSE
var/theme = "magic"

View File

@@ -1,7 +1,7 @@
//Pool noodles
/obj/item/toy/poolnoodle
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "noodle"
name = "pool noodle"
desc = "A strange, bulky, bendable toy that can annoy people."

View File

@@ -69,7 +69,7 @@
/obj/item/gun/ballistic/shotgun/toy/crossbow
name = "foam force crossbow"
desc = "A weapon favored by many overactive children. Ages 8 and up."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "foamcrossbow"
item_state = "crossbow"
mag_type = /obj/item/ammo_box/magazine/internal/shot/toy/crossbow

View File

@@ -2,7 +2,7 @@
name = "damp rag"
desc = "For cleaning up messes, you suppose."
w_class = WEIGHT_CLASS_TINY
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "rag"
item_flags = NOBLUDGEON
reagent_flags = REFILLABLE | DRAINABLE

View File

@@ -81,76 +81,129 @@
category = list("initial", "Toys")
/datum/design/autoylathe/mech/model1
name = "Toy Ripley"
name = "Toy Ripley MK-I"
id = "toymech1"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/prize/ripley
build_path = /obj/item/toy/mecha/ripley
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/model2
name = "Toy Firefighter Ripley"
name = "Toy Ripley MK-II"
id = "toymech2"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/prize/fireripley
build_path = /obj/item/toy/mecha/ripleymkii
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/contraband/model3
name = "Toy Deathsquad fireripley "
/datum/design/autoylathe/mech/model3
name = "Toy Hauler"
id = "toymech3"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/prize/deathripley
build_path = /obj/item/toy/mecha/hauler
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/model4
name = "Toy Gygax"
name = "Toy Clarke"
id = "toymech4"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/prize/gygax
build_path = /obj/item/toy/mecha/clarke
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/model5
name = "Toy Durand"
name = "Toy Odysseus"
id = "toymech5"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/prize/durand
build_path = /obj/item/toy/mecha/odysseus
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/contraband/model6
name = "Toy H.O.N.K."
/datum/design/autoylathe/mech/model6
name = "Toy Gygax"
id = "toymech6"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/prize/honk
build_path = /obj/item/toy/mecha/gygax
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/contraband/model7
name = "Toy Marauder"
/datum/design/autoylathe/mech/model7
name = "Toy Durand"
id = "toymech7"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/prize/marauder
build_path = /obj/item/toy/mecha/durand
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/contraband/model8
name = "Toy Seraph"
/datum/design/autoylathe/mech/model8
name = "Toy Savannah-Ivanov"
id = "toymech8"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/prize/seraph
build_path = /obj/item/toy/mecha/savannahivanov
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/contraband/model9
name = "Toy Mauler"
/datum/design/autoylathe/mech/model9
name = "Toy Phazon"
id = "toymech9"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/prize/mauler
build_path = /obj/item/toy/mecha/phazon
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/model10
name = "Toy Odysseus"
/datum/design/autoylathe/mech/contraband/model10
name = "Toy H.O.N.K"
id = "toymech10"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/prize/odysseus
build_path = /obj/item/toy/mecha/honk
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/model11
name = "Toy Phazon"
/datum/design/autoylathe/mech/contraband/model11
name = "Toy Dark Gygax"
id = "toymech11"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/prize/phazon
build_path = /obj/item/toy/mecha/darkgygax
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/contraband/model12
name = "Toy Reticence"
name = "Toy Mauler"
id = "toymech12"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/prize/reticence
build_path = /obj/item/toy/mecha/mauler
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/contraband/model13
name = "Toy Dark H.O.N.K"
id = "toymech13"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/mecha/darkhonk
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/contraband/model14
name = "Toy Death-Ripley"
id = "toymech14"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/mecha/deathripley
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/contraband/model15
name = "Toy Reticence"
id = "toymech15"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/mecha/reticence
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/contraband/model16
name = "Toy Marauder"
id = "toymech16"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/mecha/marauder
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/contraband/model17
name = "Toy Seraph"
id = "toymech17"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/mecha/seraph
category = list("hacked", "Figurines")
/datum/design/autoylathe/mech/model18
name = "Toy Firefighter"
id = "toymech18"
materials = list(/datum/material/plastic = 250)
build_path = /obj/item/toy/mecha/firefighter
category = list("hacked", "Figurines")
/datum/design/autoylathe/talking/AI

View File

@@ -333,7 +333,7 @@
/obj/item/spellpacket/lightningbolt
name = "\improper Lightning bolt Spell Packet"
desc = "Some birdseed wrapped in cloth that somehow crackles with electricity."
icon = 'icons/obj/toy.dmi'
icon = 'icons/obj/toys/toy.dmi'
icon_state = "snappop"
w_class = WEIGHT_CLASS_TINY

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

BIN
icons/obj/toys/toy.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@@ -724,6 +724,7 @@
#include "code\datums\elements\photosynthesis.dm"
#include "code\datums\elements\polychromic.dm"
#include "code\datums\elements\scavenging.dm"
#include "code\datums\elements\series.dm"
#include "code\datums\elements\snail_crawl.dm"
#include "code\datums\elements\spellcasting.dm"
#include "code\datums\elements\squish.dm"
@@ -1207,6 +1208,7 @@
#include "code\game\objects\items\teleprod.dm"
#include "code\game\objects\items\telescopic_iv.dm"
#include "code\game\objects\items\theft_tools.dm"
#include "code\game\objects\items\toy_mechs.dm"
#include "code\game\objects\items\toys.dm"
#include "code\game\objects\items\trash.dm"
#include "code\game\objects\items\vending_items.dm"