diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 44f4bca1c03..125fdc86a16 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -454,3 +454,7 @@ GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE))
#define VARSET_FROM_LIST_IF(L, V, C...) if(L && L[#V] && (C)) V = L[#V]
#define VARSET_TO_LIST(L, V) if(L) L[#V] = V
#define VARSET_TO_LIST_IF(L, V, C...) if(L && (C)) L[#V] = V
+
+#define DICE_NOT_RIGGED 1
+#define DICE_BASICALLY_RIGGED 2
+#define DICE_TOTALLY_RIGGED 3
diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm
index c5b9c7edc91..a1469448cad 100644
--- a/code/__DEFINES/movespeed_modification.dm
+++ b/code/__DEFINES/movespeed_modification.dm
@@ -56,3 +56,5 @@
#define MOVESPEED_ID_CYBER_THRUSTER "CYBER_IMPLANT_THRUSTER"
#define MOVESPEED_ID_JETPACK "JETPACK"
+
+#define MOVESPEED_ID_DIE_OF_FATE "DIE_OF_FATE"
diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm
index e8e833890be..303f02b9932 100644
--- a/code/game/objects/effects/effect_system/effects_smoke.dm
+++ b/code/game/objects/effects/effect_system/effects_smoke.dm
@@ -327,3 +327,9 @@
/obj/effect/particle_effect/smoke/transparent
opaque = FALSE
+
+/proc/do_smoke(range=0, location=null, smoke_type=/obj/effect/particle_effect/smoke)
+ var/datum/effect_system/smoke_spread/smoke = new
+ smoke.effect_type = smoke_type
+ smoke.set_up(range, location)
+ smoke.start()
diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm
index c6af6246bf8..7025d605ab2 100644
--- a/code/game/objects/items/dice.dm
+++ b/code/game/objects/items/dice.dm
@@ -43,12 +43,15 @@
var/sides = 6
var/result = null
var/list/special_faces = list() //entries should match up to sides var if used
- var/can_be_rigged = TRUE
- var/rigged = FALSE
+ var/microwave_riggable = TRUE
+
+ var/rigged = DICE_NOT_RIGGED
+ var/rigged_value
/obj/item/dice/Initialize()
. = ..()
- result = roll(sides)
+ if(!result)
+ result = roll(sides)
update_icon()
/obj/item/dice/suicide_act(mob/user)
@@ -166,9 +169,14 @@
/obj/item/dice/proc/diceroll(mob/user)
result = roll(sides)
- if(rigged && result != rigged)
- if(prob(CLAMP(1/(sides - 1) * 100, 25, 80)))
- result = rigged
+ if(rigged != DICE_NOT_RIGGED && result != rigged_value)
+ if(rigged == DICE_BASICALLY_RIGGED && prob(CLAMP(1/(sides - 1) * 100, 25, 80)))
+ result = rigged_value
+ else if(rigged == DICE_TOTALLY_RIGGED)
+ result = rigged_value
+
+ . = result
+
var/fake_result = roll(sides)//Daredevil isn't as good as he used to be
var/comment = ""
if(sides == 20 && result == 20)
@@ -192,6 +200,7 @@
add_overlay("[src.icon_state]-[src.result]")
/obj/item/dice/microwave_act(obj/machinery/microwave/M)
- if(can_be_rigged)
- rigged = result
+ if(microwave_riggable)
+ rigged = DICE_BASICALLY_RIGGED
+ rigged_value = result
..(M)
diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm
index 6aaba4a5a4f..5ab45b28b00 100644
--- a/code/modules/awaymissions/mission_code/Academy.dm
+++ b/code/modules/awaymissions/mission_code/Academy.dm
@@ -163,27 +163,47 @@
backpack_contents = list(/obj/item/storage/box/survival = 1)
/obj/item/dice/d20/fate
- name = "Die of Fate"
+ name = "\improper Die of Fate"
desc = "A die with twenty sides. You can feel unearthly energies radiating from it. Using this might be VERY risky."
icon_state = "d20"
sides = 20
- can_be_rigged = FALSE
- var/reusable = 1
- var/used = 0
+ microwave_riggable = FALSE
+ var/reusable = TRUE
+ var/used = FALSE
+
+/obj/item/dice/d20/fate/stealth
+ name = "d20"
+ desc = "A die with twenty sides. The preferred die to throw at the GM."
/obj/item/dice/d20/fate/one_use
- reusable = 0
+ reusable = FALSE
+
+/obj/item/dice/d20/fate/one_use/stealth
+ name = "d20"
+ desc = "A die with twenty sides. The preferred die to throw at the GM."
+
+/obj/item/dice/d20/fate/cursed
+ name = "cursed Die of Fate"
+ desc = "A die with twenty sides. You feel that rolling this is a REALLY bad idea."
+ color = "#00BB00"
+
+ rigged = DICE_TOTALLY_RIGGED
+ rigged_value = 1
/obj/item/dice/d20/fate/diceroll(mob/user)
- ..()
+ . = ..()
if(!used)
if(!ishuman(user) || !user.mind || (user.mind in SSticker.mode.wizards))
to_chat(user, "You feel the magic of the dice is restricted to ordinary humans!")
return
- if(rigged)
- effect(user,rigged)
- else
- effect(user,result)
+
+ if(!reusable)
+ used = TRUE
+
+ var/turf/T = get_turf(src)
+ T.visible_message("[src] flares briefly.")
+
+ addtimer(CALLBACK(src, .proc/effect, user, .), 1 SECONDS)
/obj/item/dice/d20/fate/equipped(mob/user, slot)
if(!ishuman(user) || !user.mind || (user.mind in SSticker.mode.wizards))
@@ -192,36 +212,39 @@
/obj/item/dice/d20/fate/proc/effect(var/mob/living/carbon/human/user,roll)
- if(!reusable)
- used = 1
- visible_message("The die flare briefly.")
+ var/turf/T = get_turf(src)
switch(roll)
if(1)
//Dust
+ T.visible_message("[user] turns to dust!")
user.dust()
if(2)
//Death
+ T.visible_message("[user] suddenly dies!")
user.death()
if(3)
//Swarm of creatures
+ T.visible_message("A swarm of creatures surround [user]!")
for(var/direction in GLOB.alldirs)
- var/turf/T = get_turf(src)
- new /mob/living/simple_animal/hostile/netherworld(get_step(T,direction))
+ new /mob/living/simple_animal/hostile/netherworld(get_step(get_turf(user),direction))
if(4)
//Destroy Equipment
- for (var/obj/item/I in user)
- if (istype(I, /obj/item/implant))
+ T.visible_message("Everything [user] is holding and wearing disappears!")
+ for(var/obj/item/I in user)
+ if(istype(I, /obj/item/implant))
continue
qdel(I)
if(5)
//Monkeying
+ T.visible_message("[user] transforms into a monkey!")
user.monkeyize()
if(6)
//Cut speed
- var/datum/species/S = user.dna.species
- S.speedmod += 1
+ T.visible_message("[user] starts moving slower!")
+ user.add_movespeed_modifier(MOVESPEED_ID_DIE_OF_FATE, update=TRUE, priority=100, multiplicative_slowdown=1)
if(7)
//Throw
+ T.visible_message("Unseen forces throw [user]!")
user.Stun(60)
user.adjustBruteLoss(50)
var/throw_dir = pick(GLOB.cardinals)
@@ -229,41 +252,54 @@
user.throw_at(throw_target, 200, 4)
if(8)
//Fueltank Explosion
- explosion(loc,-1,0,2, flame_range = 2)
+ T.visible_message("An explosion bursts into existence around [user]!")
+ explosion(get_turf(user),-1,0,2, flame_range = 2)
if(9)
//Cold
var/datum/disease/D = new /datum/disease/cold()
+ T.visible_message("[user] looks a little under the weather!")
user.ForceContractDisease(D, FALSE, TRUE)
if(10)
//Nothing
- visible_message("[src] roll perfectly.")
+ T.visible_message("Nothing seems to happen.")
if(11)
//Cookie
+ T.visible_message("A cookie appears out of thin air!")
var/obj/item/reagent_containers/food/snacks/cookie/C = new(drop_location())
+ do_smoke(0, drop_location())
C.name = "Cookie of Fate"
if(12)
//Healing
+ T.visible_message("[user] looks very healthy!")
user.revive(full_heal = 1, admin_revive = 1)
if(13)
//Mad Dosh
+ T.visible_message("Mad dosh shoots out of [src]!")
var/turf/Start = get_turf(src)
for(var/direction in GLOB.alldirs)
- var/turf/T = get_step(Start,direction)
+ var/turf/dirturf = get_step(Start,direction)
if(rand(0,1))
- new /obj/item/stack/spacecash/c1000(T)
+ new /obj/item/stack/spacecash/c1000(dirturf)
else
- var/obj/item/storage/bag/money/M = new(T)
+ var/obj/item/storage/bag/money/M = new(dirturf)
for(var/i in 1 to rand(5,50))
new /obj/item/coin/gold(M)
if(14)
//Free Gun
+ T.visible_message("An impressive gun appears!")
+ do_smoke(0, drop_location())
new /obj/item/gun/ballistic/revolver/mateba(drop_location())
if(15)
//Random One-use spellbook
+ T.visible_message("A magical looking book drops to the floor!")
+ do_smoke(0, drop_location())
new /obj/item/book/granter/spell/random(drop_location())
if(16)
//Servant & Servant Summon
+ T.visible_message("A Dice Servant appears in a cloud of smoke!")
var/mob/living/carbon/human/H = new(drop_location())
+ do_smoke(0, drop_location())
+
H.equipOutfit(/datum/outfit/butler)
var/datum/mind/servant_mind = new /datum/mind()
var/datum/antagonist/magic_servant/A = new
@@ -283,19 +319,23 @@
if(17)
//Tator Kit
+ T.visible_message("A suspicious box appears!")
new /obj/item/storage/box/syndicate(drop_location())
+ do_smoke(0, drop_location())
if(18)
//Captain ID
+ T.visible_message("A golden identification card appears!")
new /obj/item/card/id/captains_spare(drop_location())
+ do_smoke(0, drop_location())
if(19)
//Instrinct Resistance
- to_chat(user, "You feel robust.")
- var/datum/species/S = user.dna.species
- S.brutemod *= 0.5
- S.burnmod *= 0.5
- S.coldmod *= 0.5
+ T.visible_message("[user] looks very robust!")
+ user.physiology.brute_mod *= 0.5
+ user.physiology.burn_mod *= 0.5
+
if(20)
//Free wizard!
+ T.visible_message("Magic flows out of [src] and into [user]!")
user.mind.make_Wizard()
/datum/outfit/butler