Replaces the rpg loot datum with a component and makes some suffixes have real effects

This commit is contained in:
Joe Schmoe
2019-06-08 20:54:54 +02:00
parent 7a823ca965
commit bf5f972c24
12 changed files with 421 additions and 89 deletions

View File

@@ -0,0 +1,5 @@
#define AFFIX_PREFIX (1 << 0)
#define AFFIX_SUFFIX (1 << 1)
#define AFFIX_GOOD (1 << 0)
#define AFFIX_EVIL (1 << 1)

View File

@@ -0,0 +1,45 @@
/datum/component/bane
dupe_mode = COMPONENT_DUPE_ALLOWED
var/mobtype
var/speciestype
var/damage_multiplier
/datum/component/bane/Initialize(mobtype, damage_multiplier=1)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
if(ispath(mobtype, /mob/living))
src.mobtype = mobtype
else if(ispath(mobtype, /datum/species))
speciestype = mobtype
else
return COMPONENT_INCOMPATIBLE
src.damage_multiplier = damage_multiplier
/datum/component/bane/RegisterWithParent()
if(speciestype)
RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/speciesCheck)
else
RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/mobCheck)
/datum/component/bane/UnregisterFromParent()
UnregisterSignal(parent, COMSIG_ITEM_AFTERATTACK)
/datum/component/bane/proc/speciesCheck(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
if(!is_species(target, speciestype))
return
activate(source, target, user)
/datum/component/bane/proc/mobCheck(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
if(!istype(target, mobtype))
return
activate(source, target, user)
/datum/component/bane/proc/activate(obj/item/source, mob/living/target, mob/attacker)
if(attacker.a_intent != INTENT_HARM)
return
var/extra_damage = max(0, source.force * damage_multiplier)
target.apply_damage(extra_damage, source.damtype, attacker.zone_selected)

View File

@@ -0,0 +1,137 @@
/datum/component/fantasy
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
var/quality
var/canFail
var/announce
var/originalName
var/list/affixes
var/list/appliedComponents
var/static/list/affixListing
/datum/component/fantasy/Initialize(quality, list/affixes = list(), canFail=FALSE, announce=FALSE)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
src.quality = quality || randomQuality()
src.canFail = canFail
src.announce = announce
src.affixes = affixes
appliedComponents = list()
randomAffixes()
/datum/component/fantasy/Destroy()
unmodify()
affixes = null
return ..()
/datum/component/fantasy/RegisterWithParent()
var/obj/item/master = parent
originalName = master.name
modify()
/datum/component/fantasy/UnregisterFromParent()
unmodify()
/datum/component/fantasy/InheritComponent(datum/component/fantasy/newComp, original, list/arguments)
unmodify()
if(newComp)
quality += newComp.quality
canFail = newComp.canFail
announce = newComp.announce
else
arguments.len = 5 // This is done to replicate what happens when an arglist smaller than the necessary arguments is given
quality += arguments[1]
canFail = arguments[4] || canFail
announce = arguments[5] || announce
modify()
/datum/component/fantasy/proc/randomQuality()
var/quality = pick(1;15, 2;14, 2;13, 2;12, 3;11, 3;10, 3;9, 4;8, 4;7, 4;6, 5;5, 5;4, 5;3, 6;2, 6;1, 6;0)
if(prob(50))
quality = -quality
return quality
/datum/component/fantasy/proc/randomAffixes(force)
if(!affixListing)
affixListing = list()
for(var/T in subtypesof(/datum/fantasy_affix))
var/datum/fantasy_affix/affix = new T
affixListing[affix] = affix.weight
var/usedSlots = NONE
for(var/i in affixes)
var/datum/fantasy_affix/affix = i
usedSlots |= affix.placement
var/alignment
if(quality >= 0)
alignment |= AFFIX_GOOD
if(quality <= 0)
alignment |= AFFIX_EVIL
for(var/i in 1 to max(1, abs(quality))) // We want at least 1 affix applied
var/datum/fantasy_affix/affix = pickweight(affixListing)
if(affix.placement & usedSlots)
continue
if(!(affix.alignment & alignment))
continue
affixes += affix
usedSlots |= affix.placement
/datum/component/fantasy/proc/modify()
var/obj/item/master = parent
master.force = max(0, master.force + quality)
master.throwforce = max(0, master.throwforce + quality)
master.armor = master.armor.modifyAllRatings(quality)
var/newName = originalName
for(var/i in affixes)
var/datum/fantasy_affix/affix = i
newName = affix.apply(src, newName)
if(quality != 0)
newName = "[newName] [quality > 0 ? "+" : ""][quality]"
if(canFail && prob((quality - 9)*10))
var/turf/place = get_turf(parent)
place.visible_message("<span class='danger'>[parent] <span class='inathneq_large'>violently glows blue</span> for a while, then evaporates.</span>")
master.burn()
return
else if(announce)
announce()
master.name = newName
/datum/component/fantasy/proc/unmodify()
var/obj/item/master = parent
for(var/i in affixes)
var/datum/fantasy_affix/affix = i
affix.remove(src)
for(var/i in appliedComponents)
qdel(i)
master.force = max(0, master.force - quality)
master.throwforce = max(0, master.throwforce - quality)
master.armor = master.armor.modifyAllRatings(-quality)
master.name = originalName
/datum/component/fantasy/proc/announce()
var/turf/location = get_turf(parent)
var/span
var/effect_description
if(quality >= 0)
span = "<span class='notice'>"
effect_description = "<span class='heavy_brass'>shimmering golden glow</span>"
else
span = "<span class='danger'>"
effect_description = "<span class='umbra_emphasis'>mottled black glow</span>"
location.visible_message("[span][originalName] is covered by a [effect_description] and then transforms into [parent]!</span>")

View File

@@ -0,0 +1,9 @@
/datum/fantasy_affix
var/placement // A bitflag of "slots" this affix takes up, for example pre/suffix
var/alignment
var/weight = 10
/datum/fantasy_affix/proc/apply(datum/component/fantasy/comp, newName)
return newName
/datum/fantasy_affix/proc/remove(datum/component/fantasy/comp)

View File

@@ -0,0 +1,49 @@
/datum/fantasy_affix/cosmetic_prefixes
placement = AFFIX_PREFIX
alignment = AFFIX_GOOD | AFFIX_EVIL
var/list/goodPrefixes
var/list/badPrefixes
/datum/fantasy_affix/cosmetic_prefixes/New()
goodPrefixes = list(
"greater",
"major",
"blessed",
"superior",
"empowered",
"honed",
"true",
"glorious",
"robust",
)
badPrefixes = list(
"lesser",
"minor",
"blighted",
"inferior",
"enfeebled",
"rusted",
"unsteady",
"tragic",
"gimped",
"cursed",
)
weight = (length(goodPrefixes) + length(badPrefixes)) * 10
/datum/fantasy_affix/cosmetic_prefixes/apply(datum/component/fantasy/comp, newName)
if(comp.quality > 0 || (comp.quality == 0 && prob(50)))
return "[pick(goodPrefixes)] [newName]"
else
return "[pick(badPrefixes)] [newName]"
/datum/fantasy_affix/tactical
placement = AFFIX_PREFIX
alignment = AFFIX_GOOD
weight = 1 // Very powerful, no one should have such power
/datum/fantasy_affix/tactical/apply(datum/component/fantasy/comp, newName)
var/obj/item/master = comp.parent
comp.appliedComponents += master.AddComponent(/datum/component/tactical)
return "tactical [newName]"

View File

@@ -0,0 +1,101 @@
/datum/fantasy_affix/cosmetic_suffixes
placement = AFFIX_SUFFIX
alignment = AFFIX_GOOD | AFFIX_EVIL
var/list/goodSuffixes
var/list/badSuffixes
/datum/fantasy_affix/cosmetic_suffixes/New()
goodSuffixes = list(
"dexterity",
"constitution",
"intelligence",
"wisdom",
"charisma",
"the forest",
"the hills",
"the plains",
"the sea",
"the sun",
"the moon",
"the void",
"the world",
"many secrets",
"many tales",
"many colors",
"rending",
"sundering",
"the night",
"the day",
)
badSuffixes = list(
"draining",
"burden",
"discomfort",
"awkwardness",
"poor hygiene",
"timidity",
)
weight = (length(goodSuffixes) + length(badSuffixes)) * 10
/datum/fantasy_affix/cosmetic_suffixes/apply(datum/component/fantasy/comp, newName)
if(comp.quality > 0 || (comp.quality == 0 && prob(50)))
return "[newName] of [pick(goodSuffixes)]"
else
return "[newName] of [pick(badSuffixes)]"
//////////// Good suffixes
/datum/fantasy_affix/bane
placement = AFFIX_SUFFIX
alignment = AFFIX_GOOD
weight = 20
/datum/fantasy_affix/bane/apply(datum/component/fantasy/comp, newName)
. = ..()
// This is set up to be easy to add to these lists as I expect it will need modifications
var/static/list/possible_mobtypes
if(!possible_mobtypes)
// The base list of allowed mob/species types
possible_mobtypes = typecacheof(list(
/mob/living/simple_animal,
/mob/living/carbon,
/datum/species,
))
// Some particular types to disallow if they're too broad/abstract
possible_mobtypes -= list(
/mob/living/simple_animal/hostile,
)
// Some types to remove them and their subtypes
possible_mobtypes -= typecacheof(list(
/mob/living/carbon/human/species,
))
var/mob/picked_mobtype = pick(possible_mobtypes)
// This works even with the species picks since we're only accessing the name
var/obj/item/master = comp.parent
comp.appliedComponents += master.AddComponent(/datum/component/bane, picked_mobtype)
return "[newName] of [initial(picked_mobtype.name)] slaying"
/datum/fantasy_affix/strength
placement = AFFIX_SUFFIX
alignment = AFFIX_GOOD
/datum/fantasy_affix/strength/apply(datum/component/fantasy/comp, newName)
. = ..()
var/obj/item/master = comp.parent
comp.appliedComponents += master.AddComponent(/datum/component/knockback, CEILING(comp.quality/2, 1))
return "[newName] of strength"
//////////// Bad suffixes
/datum/fantasy_affix/fool
placement = AFFIX_SUFFIX
alignment = AFFIX_EVIL
/datum/fantasy_affix/fool/apply(datum/component/fantasy/comp, newName)
. = ..()
var/obj/item/master = comp.parent
comp.appliedComponents += master.AddComponent(/datum/component/squeak/bikehorn)
return "[newName] of the fool"

View File

@@ -0,0 +1,22 @@
/datum/component/knockback
var/throw_distance
/datum/component/knockback/Initialize(throw_distance=1)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
src.throw_distance = throw_distance
/datum/component/knockback/RegisterWithParent()
RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/afterattack_react)
/datum/component/knockback/UnregisterFromParent()
UnregisterSignal(parent, COMSIG_ITEM_AFTERATTACK)
/datum/component/knockback/proc/afterattack_react(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
if(!ismovableatom(target) || !proximity_flag)
return
var/obj/item/master = parent
var/atom/movable/throwee = target
var/atom/throw_target = get_edge_target_turf(throwee, get_dir(master, throwee))
throwee.safe_throw_at(throw_target, throw_distance, 1, user)

View File

@@ -0,0 +1,34 @@
/datum/component/tactical
var/allowed_slot
/datum/component/tactical/Initialize(allowed_slot)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
src.allowed_slot = allowed_slot
/datum/component/tactical/RegisterWithParent()
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/modify)
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/unmodify)
/datum/component/tactical/UnregisterFromParent()
unmodify()
/datum/component/fantasy/Destroy()
unmodify()
return ..()
/datum/component/tactical/proc/modify(obj/item/source, mob/user, slot)
if(allowed_slot && slot != allowed_slot)
unmodify()
return
var/obj/item/master = parent
var/image/I = image(icon = master.icon, icon_state = master.icon_state, loc = user)
I.copy_overlays(master)
I.override = TRUE
source.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "sneaking_mission", I)
I.layer = ABOVE_MOB_LAYER
/datum/component/tactical/proc/unmodify(obj/item/source, mob/user)
user.remove_alt_appearance("sneaking_mission")

View File

@@ -94,9 +94,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
// non-clothing items
var/datum/dog_fashion/dog_fashion = null
var/datum/rpg_loot/rpg_loot = null
//Tooltip vars
var/force_string //string form of an item's force. Edit this var only to set a custom force string
var/last_force_string_check = 0
@@ -121,7 +118,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
actions_types = null
if(GLOB.rpg_loot_items)
rpg_loot = new(src)
AddComponent(/datum/component/fantasy)
if(force_string)
item_flags |= FORCE_STRING_OVERRIDE
@@ -146,7 +143,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
m.temporarilyRemoveItemFromInventory(src, TRUE)
for(var/X in actions)
qdel(X)
QDEL_NULL(rpg_loot)
return ..()
/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self)

View File

@@ -313,6 +313,7 @@
throw_speed = 2
throw_range = 4
<<<<<<< HEAD
/obj/item/twohanded/required/kirbyplants/equipped(mob/living/user)
var/image/I = image(icon = 'yogstation/icons/obj/flora/plants.dmi' , icon_state = src.icon_state, loc = user) //yogs changed icon path
@@ -325,6 +326,11 @@
/obj/item/twohanded/required/kirbyplants/dropped(mob/living/user)
..()
user.remove_alt_appearance("sneaking_mission")
=======
/obj/item/twohanded/required/kirbyplants/Initialize()
. = ..()
AddComponent(/datum/component/tactical)
>>>>>>> 66cab55f28... Replaces the rpg loot datum with a component and makes some suffixes have real effects (#44044)
/obj/item/twohanded/required/kirbyplants/random
icon = 'icons/obj/flora/_flora.dmi'

View File

@@ -8,11 +8,12 @@
/datum/round_event/wizard/rpgloot/start()
var/upgrade_scroll_chance = 0
for(var/obj/item/I in world)
CHECK_TICK
if(!(I.flags_1 & INITIALIZED_1))
continue
if(!istype(I.rpg_loot))
I.rpg_loot = new(I)
I.AddComponent(/datum/component/fantasy)
if(istype(I, /obj/item/storage))
var/obj/item/storage/S = I
@@ -44,33 +45,7 @@
if(!proximity || !istype(target))
return
var/datum/rpg_loot/rpg_loot_datum = target.rpg_loot
var/turf/T = get_turf(target)
if(!istype(rpg_loot_datum))
var/original_name = "[target]"
target.rpg_loot = rpg_loot_datum = new /datum/rpg_loot(target)
var/span
var/effect_description
if(target.rpg_loot.quality >= 0)
span = "<span class='notice'>"
effect_description = "<span class='heavy_brass'>shimmering golden shield</span>"
else
span = "<span class='danger'>"
effect_description = "<span class='umbra_emphasis'>mottled black glow</span>"
T.visible_message("[span][original_name] is covered by a [effect_description] and then transforms into [target]!</span>")
else
var/quality = rpg_loot_datum.quality
if(can_backfire && quality > 9 && prob((quality - 9)*10))
T.visible_message("<span class='danger'>[target] <span class='inathneq_large'>violently glows blue</span> for a while, then evaporates.</span>")
target.burn()
else
T.visible_message("<span class='notice'>[target] <span class='inathneq_small'>glows blue</span> and seems vaguely \"better\"!</span>")
rpg_loot_datum.modify(upgrade_amount)
target.AddComponent(/datum/component/fantasy, upgrade_amount, null, null, can_backfire, TRUE)
if(--uses <= 0)
qdel(src)
@@ -80,58 +55,3 @@
desc = "Somehow, this piece of paper can be applied to items to make them \"better\". This scroll is made from the tongues of dead paper wizards, and can be used an unlimited number of times, with no drawbacks."
uses = INFINITY
can_backfire = FALSE
/datum/rpg_loot
var/positive_prefix = "okay"
var/negative_prefix = "weak"
var/suffix = "something profound"
var/quality = 0
var/obj/item/attached
var/original_name
/datum/rpg_loot/New(attached_item=null)
attached = attached_item
randomise()
/datum/rpg_loot/Destroy()
attached = null
/datum/rpg_loot/proc/randomise()
var/static/list/prefixespositive = list("greater", "major", "blessed", "superior", "empowered", "honed", "true", "glorious", "robust")
var/static/list/prefixesnegative = list("lesser", "minor", "blighted", "inferior", "enfeebled", "rusted", "unsteady", "tragic", "gimped")
var/static/list/suffixes = list("orc slaying", "elf slaying", "corgi slaying", "strength", "dexterity", "constitution", "intelligence", "wisdom", "charisma", "the forest", "the hills", "the plains", "the sea", "the sun", "the moon", "the void", "the world", "the fool", "many secrets", "many tales", "many colors", "rending", "sundering", "the night", "the day")
var/new_quality = pick(1;15, 2;14, 2;13, 2;12, 3;11, 3;10, 3;9, 4;8, 4;7, 4;6, 5;5, 5;4, 5;3, 6;2, 6;1, 6;0)
suffix = pick(suffixes)
positive_prefix = pick(prefixespositive)
negative_prefix = pick(prefixesnegative)
if(prob(50))
new_quality = -new_quality
modify(new_quality)
/datum/rpg_loot/proc/rename()
var/obj/item/I = attached
if(!original_name)
original_name = I.name
if(quality < 0)
I.name = "[negative_prefix] [original_name] of [suffix] [quality]"
else if(quality == 0)
I.name = "[original_name] of [suffix]"
else if(quality > 0)
I.name = "[positive_prefix] [original_name] of [suffix] +[quality]"
/datum/rpg_loot/proc/modify(quality_mod)
var/obj/item/I = attached
quality += quality_mod
I.force = max(0,I.force + quality_mod)
I.throwforce = max(0,I.throwforce + quality_mod)
I.armor = I.armor.modifyAllRatings(quality)
rename()

View File

@@ -44,6 +44,7 @@
#include "code\__DEFINES\economy.dm"
#include "code\__DEFINES\events.dm"
#include "code\__DEFINES\exports.dm"
#include "code\__DEFINES\fantasy_affixes.dm"
#include "code\__DEFINES\flags.dm"
#include "code\__DEFINES\food.dm"
#include "code\__DEFINES\footsteps.dm"
@@ -336,6 +337,7 @@
#include "code\datums\components\_component.dm"
#include "code\datums\components\anti_magic.dm"
#include "code\datums\components\armor_plate.dm"
#include "code\datums\components\bane.dm"
#include "code\datums\components\beetlejuice.dm"
#include "code\datums\components\butchering.dm"
#include "code\datums\components\caltrop.dm"
@@ -353,6 +355,7 @@
#include "code\datums\components\heirloom.dm"
#include "code\datums\components\infective.dm"
#include "code\datums\components\jousting.dm"
#include "code\datums\components\knockback.dm"
#include "code\datums\components\knockoff.dm"
#include "code\datums\components\lockon_aiming.dm"
#include "code\datums\components\magnetic_catch.dm"
@@ -378,6 +381,7 @@
#include "code\datums\components\squeak.dm"
#include "code\datums\components\stationloving.dm"
#include "code\datums\components\swarming.dm"
#include "code\datums\components\tactical.dm"
#include "code\datums\components\tether.dm"
#include "code\datums\components\thermite.dm"
#include "code\datums\components\uplink.dm"
@@ -385,6 +389,10 @@
#include "code\datums\components\wearertargeting.dm"
#include "code\datums\components\wet_floor.dm"
#include "code\datums\components\decals\blood.dm"
#include "code\datums\components\fantasy\_fantasy.dm"
#include "code\datums\components\fantasy\affix.dm"
#include "code\datums\components\fantasy\prefixes.dm"
#include "code\datums\components\fantasy\suffixes.dm"
#include "code\datums\components\storage\storage.dm"
#include "code\datums\components\storage\concrete\_concrete.dm"
#include "code\datums\components\storage\concrete\bag_of_holding.dm"