diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index 047157578b7..f59b10e79b5 100644 --- a/code/datums/components/crafting/crafting.dm +++ b/code/datums/components/crafting/crafting.dm @@ -500,3 +500,13 @@ if(!learned_recipes) learned_recipes = list() learned_recipes |= R + +/datum/mind/proc/has_crafting_recipe(mob/user, potential_recipe) + if(!learned_recipes) + return FALSE + if(!istype(potential_recipe, /datum/crafting_recipe)) + CRASH("Non-crafting recipe passed to has_crafting_recipe") + for(var/recipe in user.mind.learned_recipes) + if(recipe == potential_recipe) + return TRUE + return FALSE diff --git a/code/datums/components/crafting/recipes.dm b/code/datums/components/crafting/recipes.dm index bd9dcc0f490..7d66f8b4d4b 100644 --- a/code/datums/components/crafting/recipes.dm +++ b/code/datums/components/crafting/recipes.dm @@ -1839,5 +1839,23 @@ qdel(toilet) to_chat(user, span_notice("[user] attaches the flamethrower to the repurposed toilet.")) +/datum/crafting_recipe/house_edge + name = "House Edge" + result = /obj/item/house_edge + always_available = FALSE + tool_behaviors = list(TOOL_WRENCH, TOOL_SCREWDRIVER, TOOL_WELDER) + reqs = list( + /obj/item/v8_engine = 1, + /obj/item/weaponcrafting/receiver = 1, + /obj/item/assembly/igniter = 1, + /obj/item/stack/sheet/iron = 2, + /obj/item/knife = 1, + /obj/item/weldingtool = 1, + /obj/item/roulette_wheel_beacon = 1, + ) + time = 10 SECONDS + category = CAT_WEAPONRY + subcategory = CAT_WEAPON + #undef CRAFTING_MACHINERY_CONSUME #undef CRAFTING_MACHINERY_USE diff --git a/code/game/objects/items/v8_engine.dm b/code/game/objects/items/v8_engine.dm new file mode 100644 index 00000000000..6f4e309a431 --- /dev/null +++ b/code/game/objects/items/v8_engine.dm @@ -0,0 +1,117 @@ +#define ENGINE_COOLDOWN 5 SECONDS +#define DASH_COOLDOWN 2.5 SECONDS +#define HOUSE_EDGE_ICONS_MAX 3 +#define HOUSE_EDGE_ICONS_MIN 0 + +/obj/item/v8_engine + name = "ancient engine" + desc = "An extremely well perserved, massive V8 engine from the early 2000s. It seems to be missing the rest of the vehicle. There's a tiny label on the side." + icon = 'icons/obj/weapons/items_and_weapons.dmi' + icon_state = "v8_engine" + w_class = WEIGHT_CLASS_HUGE + force = 5 + throwforce = 15 + throw_range = 1 + throw_speed = 1 + COOLDOWN_DECLARE(engine_sound_cooldown) + +/obj/item/v8_engine/Initialize(mapload) + . = ..() + AddComponent(/datum/component/two_handed, require_twohands=TRUE, force_unwielded=5, force_wielded=5) + +/obj/item/v8_engine/attack_self(mob/user, modifiers) + . = ..() + if (!COOLDOWN_FINISHED(src, engine_sound_cooldown)) + return + playsound(src, 'sound/items/car_engine_start.ogg', vol = 75, vary = FALSE, extrarange = 3) + Shake(7, 7, ENGINE_COOLDOWN) + to_chat(user, span_notice("Darn thing... it's too old to keep on without retrofitting it! Without modifications, it works like it's junk.")) + COOLDOWN_START(src, engine_sound_cooldown, ENGINE_COOLDOWN) + +/obj/item/v8_engine/examine_more(mob/user) + . = ..() + INVOKE_ASYNC(src, .proc/start_learning_recipe, user) + +/obj/item/v8_engine/proc/start_learning_recipe(mob/user) + var/datum/crafting_recipe/house_edge/edge + if(!user.mind) + return + if(user.mind.has_crafting_recipe(user = user, potential_recipe = edge)) + return + to_chat(user, span_notice("You peer at the label on the side, reading about some unique modifications that could be made to the engine...")) + if(do_after(user, 15 SECONDS, src)) + user.mind.teach_crafting_recipe(edge) + to_chat(user, span_notice("You learned how to make the House Edge.")) + + +/obj/item/house_edge + name = "House Edge" + desc = "Dangerous. Loud. Sleek. It has a built in roulette wheel. This thing could easily rip your arm off if you're not careful." + icon = 'icons/obj/weapons/items_and_weapons.dmi' + icon_state = "house_edge0" + inhand_icon_state = "house_edge0" + lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + w_class = WEIGHT_CLASS_HUGE + sharpness = SHARP_EDGED + force = 12 + throwforce = 10 + throw_range = 5 + throw_speed = 1 + hitsound = 'sound/items/car_engine_start.ogg' + /// The number of charges the house edge has accrued through 2-handed hits, to charge a more powerful charge attack. + var/fire_charges = 0 + ///Sound played when wielded. + var/active_hitsound = 'sound/items/house_edge_hit.ogg' + ///Datum that tracks weapon dashing for the fire_charge system + var/datum/action/innate/dash/charge + COOLDOWN_DECLARE(fire_charge_cooldown) + +/obj/item/house_edge/Initialize(mapload) + . = ..() + AddComponent(/datum/component/two_handed, force_unwielded = 12, force_wielded = 22, attacksound = active_hitsound) + RegisterSignal(src, list(COMSIG_ITEM_DROPPED, COMSIG_MOVABLE_PRE_THROW, COMSIG_ITEM_ATTACK_SELF), .proc/reset_charges) + +/obj/item/house_edge/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + . = ..() + if(!ismob(target)) + return + if(HAS_TRAIT(src, TRAIT_WIELDED)) + //Add a fire charge to a max of 3, updates icon_state. + fire_charges = clamp((fire_charges + 1), HOUSE_EDGE_ICONS_MIN, HOUSE_EDGE_ICONS_MAX) + icon_state = "house_edge[fire_charges]" + COOLDOWN_RESET(src, fire_charge_cooldown) + else + //Lose a fire charge to a min of 0, updates icon_state. + fire_charges = clamp((fire_charges - 1), HOUSE_EDGE_ICONS_MIN, HOUSE_EDGE_ICONS_MAX) + icon_state = "house_edge[fire_charges]" + do_sparks(number = 0, cardinal_only = TRUE, source = src) + +/obj/item/house_edge/afterattack_secondary(atom/target, mob/user, proximity_flag, click_parameters) + if(!COOLDOWN_FINISHED(src, fire_charge_cooldown)) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + if(fire_charges <= 0) + balloon_alert(user, "no fire charges!") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + user.throw_at(target = get_turf(target), range = 2 * fire_charges, speed = 5, thrower = user, spin = FALSE, gentle = FALSE, quickstart = TRUE) + COOLDOWN_START(src, fire_charge_cooldown, DASH_COOLDOWN) + reset_charges(on_dash = TRUE) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/item/house_edge/update_icon_state() + inhand_icon_state = HAS_TRAIT(src, TRAIT_WIELDED) ? "house_edge1" : "house_edge0" + return ..() + +/obj/item/house_edge/proc/reset_charges(on_dash = FALSE) + if(!COOLDOWN_FINISHED(src, fire_charge_cooldown) && !on_dash) + return + if(fire_charges) + balloon_alert_to_viewers("charges lost!") + fire_charges = 0 + icon_state = "house_edge[fire_charges]" + update_icon() + +#undef ENGINE_COOLDOWN +#undef DASH_COOLDOWN +#undef HOUSE_EDGE_ICONS_MAX +#undef HOUSE_EDGE_ICONS_MIN diff --git a/code/modules/cargo/markets/market_items/misc.dm b/code/modules/cargo/markets/market_items/misc.dm index c96403fa30c..155c030af8a 100644 --- a/code/modules/cargo/markets/market_items/misc.dm +++ b/code/modules/cargo/markets/market_items/misc.dm @@ -76,3 +76,22 @@ price_max = CARGO_CRATE_VALUE * 5 stock_max = 2 availability_prob = 30 + +/datum/market_item/misc/roulette + name = "Roulette Beacon" + desc = "Start your own underground casino, wherever you go. One use only. No refunds." + item = /obj/item/roulette_wheel_beacon + price_min = CARGO_CRATE_VALUE * 1 + price_max = CARGO_CRATE_VALUE * 2.5 + stock_max = 3 + availability_prob = 50 + + +/datum/market_item/misc/v8_engine + name = "Genuine V8 Engine (Perserved)" + desc = "Hey greasemonkeys, you ready to start those engines? Want to start racing through the halls and making some tighter turns on the interstellar beltway? Then you need this classic engine." + item = /obj/item/v8_engine + price_min = CARGO_CRATE_VALUE * 4 + price_max = CARGO_CRATE_VALUE * 6 + stock_max = 1 + availability_prob = 15 diff --git a/icons/mob/inhands/weapons/swords_lefthand.dmi b/icons/mob/inhands/weapons/swords_lefthand.dmi index 0546e5adfa9..8dfada39e21 100644 Binary files a/icons/mob/inhands/weapons/swords_lefthand.dmi and b/icons/mob/inhands/weapons/swords_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/swords_righthand.dmi b/icons/mob/inhands/weapons/swords_righthand.dmi index fdf3cce8510..4ca37418be2 100644 Binary files a/icons/mob/inhands/weapons/swords_righthand.dmi and b/icons/mob/inhands/weapons/swords_righthand.dmi differ diff --git a/icons/obj/weapons/items_and_weapons.dmi b/icons/obj/weapons/items_and_weapons.dmi index 7ed6cb9bfa7..07855ccf21b 100644 Binary files a/icons/obj/weapons/items_and_weapons.dmi and b/icons/obj/weapons/items_and_weapons.dmi differ diff --git a/sound/items/car_engine_start.ogg b/sound/items/car_engine_start.ogg new file mode 100644 index 00000000000..0898e76d02d Binary files /dev/null and b/sound/items/car_engine_start.ogg differ diff --git a/sound/items/house_edge_hit.ogg b/sound/items/house_edge_hit.ogg new file mode 100644 index 00000000000..e85e15f4ee4 Binary files /dev/null and b/sound/items/house_edge_hit.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 47a30cc2f59..396d1cb16a3 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1657,6 +1657,7 @@ #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\v8_engine.dm" #include "code\game\objects\items\vending_items.dm" #include "code\game\objects\items\virgin_mary.dm" #include "code\game\objects\items\wall_mounted.dm"