Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions maplestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -6820,7 +6820,9 @@
#include "maplestation_modules\story_content\shiro_equipment\code\shiroclothing.dm"
#include "maplestation_modules\story_content\story_posters\code\contraband.dm"
#include "maplestation_modules\story_content\stranger_equipment\code\strangerclothing.dm"
#include "maplestation_modules\story_content\volkan_equipment\code\clockworktoys.dm"
#include "maplestation_modules\story_content\volkan_equipment\code\councilgifts.dm"
#include "maplestation_modules\story_content\volkan_equipment\code\mini_forklift.dm"
#include "maplestation_modules\story_content\volkan_equipment\code\sunitems.dm"
#include "maplestation_modules\story_content\volkan_equipment\code\volkancomponents.dm"
#include "maplestation_modules\story_content\volkan_equipment\code\volkanitems.dm"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
#define SPECIAL_ATTACK_HEAL 1
#define SPECIAL_ATTACK_DAMAGE 2
#define SPECIAL_ATTACK_UTILITY 3
#define SPECIAL_ATTACK_OTHER 4

#define MAX_BATTLE_LENGTH 50

/obj/item/toy/mecha/clockwork
name = "clockwork toy"
icon = 'maplestation_modules/story_content/volkan_equipment/icons/clockworkgifts.dmi'
desc = "A metal clockwork toy with a small windup key underneath."
icon_state = "bug"
verb_say = "clicks"
verb_ask = "ticks"
verb_exclaim = "clacks"
verb_yell = "clacks"
max_combat_health = 4
special_attack_type = SPECIAL_ATTACK_DAMAGE
special_attack_cry = "Bzz!!!"

/obj/item/toy/mecha/clockwork/Initialize(mapload)
. = ..()
RemoveElement(/datum/element/series, /obj/item/toy/mecha, "Mini-Mecha action figures")
AddElement(/datum/element/series, /obj/item/toy/mecha/clockwork, "CaLE's Handmade Clockwork Toys")

/**
* A Modular redo of this proc. It is the exact same thing as the original but with different verbs, etc. I want this cool thing but they are not plastic!
*/
/obj/item/toy/mecha/clockwork/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 little battle!"), \
span_danger("You collide [attacker] into [src], sparking a battle!"), \
span_hear("You hear metal clinking onto metal!"), 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/effects/footstep/rustystep1.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 metal clinking!"), 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 metal clinking!"), 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 metal clinking!"), 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 metal clinking!"), 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 metal clinking!"), 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/effects/footstep/rustystep1.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 metal clinking!"), 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("Tktktktk!", "You hear a happy buzz!*")

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 losing!"), \
span_boldnotice("Both [src] and [attacker] have lost!"))
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("CLkclkclk!")
//don't want to make this a one sided conversation
quiet? attacker.say("CLkclkclk!") : attacker.say("Buzzes!*")

in_combat = FALSE
attacker.in_combat = FALSE

combat_health = max_combat_health
attacker.combat_health = attacker.max_combat_health

return


/obj/item/toy/mecha/clockwork/snake
name = "clockwork snake"
icon_state = "snake"
max_combat_health = 4
special_attack_type = SPECIAL_ATTACK_DAMAGE
special_attack_cry = "Sssssss..."

/obj/item/toy/mecha/clockwork/mothroach
name = "clockwork mothroach"
icon_state = "mothroach"
max_combat_health = 5
special_attack_type = SPECIAL_ATTACK_HEAL
special_attack_cry = "Bzzzz!"

/obj/item/toy/mecha/clockwork/bird
name = "clockwork parakeet"
icon_state = "bird"
max_combat_health = 3
special_attack_type = SPECIAL_ATTACK_UTILITY
special_attack_cry = "Keeek!"

/obj/item/toy/mecha/clockwork/cat
name = "clockwork cat"
icon_state = "cat"
max_combat_health = 3
special_attack_type = SPECIAL_ATTACK_DAMAGE
special_attack_cry = "Meow!"
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/obj/vehicle/ridden/mini_forklift
name = "mini forklift"
icon = 'maplestation_modules/story_content/volkan_equipment/icons/forklift.dmi'
desc = "A mini novelty but still usable electric forklift built by CaLE. It is a tight fit! It is too small to hold crates, but it is the perfect size to hold flatpacks."
icon_state = "mini_forklift"
max_integrity = 150
armor_type = /datum/armor/mini_forklift
integrity_failure = 0.5
are_legs_exposed = FALSE
var/cover_iconstate = "mini_forklift_cover"
layer = OBJ_LAYER

#define MAX_FLAT_PACKS 4

/datum/armor/mini_forklift
melee = 60
bullet = 25
laser = 20
bomb = 50
fire = 60
acid = 60

/obj/vehicle/ridden/mini_forklift/atom_deconstruct(disassembled)
for(var/atom/movable/content as anything in contents)
content.forceMove(drop_location())

/obj/vehicle/ridden/mini_forklift/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = NONE
if(isnull(held_item))
return

if(istype(held_item, /obj/item/flatpack))
context[SCREENTIP_CONTEXT_LMB] = "Load pack"
return CONTEXTUAL_SCREENTIP_SET

/obj/vehicle/ridden/mini_forklift/examine(mob/user)
. = ..()
if(!in_range(user, src) && !isobserver(user))
return

. += "From bottom to top, this forklift is holding:"
for(var/obj/item/flatpack as anything in contents)
. += flatpack.name

/obj/vehicle/ridden/mini_forklift/attack_hand(mob/user, list/modifiers)
. = ..()
if(.)
return
user.put_in_hands(contents[length(contents)]) //topmost box
update_appearance(UPDATE_OVERLAYS)

/obj/vehicle/ridden/mini_forklift/item_interaction(mob/living/user, obj/item/attacking_item, params)
if(!istype(attacking_item, /obj/item/flatpack) || user.combat_mode || attacking_item.flags_1 & HOLOGRAM_1 || attacking_item.item_flags & ABSTRACT)
return ITEM_INTERACT_SKIP_TO_ATTACK

if (length(contents) >= MAX_FLAT_PACKS)
balloon_alert(user, "full!")
return ITEM_INTERACT_BLOCKING
if (!user.transferItemToLoc(attacking_item, src))
return ITEM_INTERACT_BLOCKING
update_appearance(UPDATE_OVERLAYS)
return ITEM_INTERACT_SUCCESS

/obj/vehicle/ridden/mini_forklift/Initialize(mapload)
. = ..()
AddElement(/datum/element/ridable, /datum/component/riding/vehicle/forklift)

/obj/vehicle/ridden/mini_forklift/post_buckle_mob(mob/living/user)
. = ..()
update_appearance()

/obj/vehicle/ridden/mini_forklift/post_unbuckle_mob()
. = ..()
update_appearance()

/obj/vehicle/ridden/mini_forklift/generate_actions()
. = ..()
initialize_controller_action_type(/datum/action/vehicle/ridden/horn, VEHICLE_CONTROL_DRIVE)

/obj/vehicle/ridden/mini_forklift/update_overlays()
. = ..()
if(has_buckled_mobs())
. += mutable_appearance(icon, cover_iconstate, ABOVE_MOB_LAYER, appearance_flags = KEEP_APART)

var/offset = 0
for(var/item in contents)
var/mutable_appearance/flatpack_overlay = mutable_appearance(icon, "flatcart_flat", layer = ABOVE_MOB_LAYER + (offset * 0.01))
flatpack_overlay.pixel_y = offset
offset += 5
. += flatpack_overlay

/datum/component/riding/vehicle/forklift
vehicle_move_delay = 1.75
ride_check_flags = RIDER_NEEDS_LEGS | RIDER_NEEDS_ARMS | UNBUCKLE_DISABLED_RIDER

/datum/component/riding/vehicle/forklift/get_parent_offsets_and_layers()
. = ..()
return list(
TEXT_NORTH = list(0, 0, BELOW_MOB_LAYER),
TEXT_SOUTH = list(0, -3, BELOW_MOB_LAYER),
TEXT_EAST = list(0, 0, BELOW_MOB_LAYER),
TEXT_WEST = list(0, 0, BELOW_MOB_LAYER),
)

/datum/component/riding/vehicle/forklift/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list( 1, 0),
TEXT_SOUTH = list( 0, 2),
TEXT_EAST = list(-5, 0),
TEXT_WEST = list( 5, 0),
)

#undef MAX_FLAT_PACKS

//Honk honk!!
/datum/action/vehicle/ridden/horn
check_flags = AB_CHECK_HANDS_BLOCKED | AB_CHECK_CONSCIOUS
name = "Honk Horn"
desc = "Honk your vehicle's horn."
button_icon_state = "car_horn"
var/hornsound = 'sound/items/carhorn.ogg'

/datum/action/vehicle/ridden/horn/Trigger(trigger_flags)
//Yes, I did put no cooldown. Yes, it was on purpose. Horns must be spammable.
vehicle_target.visible_message(span_danger("The forklift loudly honks!"))
to_chat(owner, span_notice("You press the horn."))
playsound(vehicle_target, hornsound, 75)
Binary file not shown.
Binary file not shown.
Loading