diff --git a/SQL/migrate/V028__newscaster_player_news.sql b/SQL/migrate/V028__newscaster_player_news.sql
new file mode 100644
index 00000000000..4576f388b01
--- /dev/null
+++ b/SQL/migrate/V028__newscaster_player_news.sql
@@ -0,0 +1,13 @@
+--
+-- Serverside changes to allow News published by players
+--
+ALTER TABLE `ss13_news_stories`
+ CHANGE COLUMN `time_stamp` `publish_at` DATETIME NULL DEFAULT NULL AFTER `is_admin_message`,
+ ADD COLUMN `publish_until` DATETIME NULL DEFAULT NULL AFTER `publish_at`,
+ ADD COLUMN `ic_timestamp` DATETIME NULL DEFAULT NULL AFTER `publish_until`,
+ ADD COLUMN `approved_by` VARCHAR(50) NULL DEFAULT NULL AFTER `created_at`,
+ ADD COLUMN `approved_at` DATETIME NULL DEFAULT NULL AFTER `approved_by`,
+ ADD COLUMN `url` VARCHAR(250) NULL DEFAULT NULL AFTER `publish_until`;
+
+ALTER TABLE `ss13_news_channels`
+ CHANGE COLUMN `announcement` `announcement` VARCHAR(200) NULL DEFAULT NULL COLLATE 'utf8_bin' AFTER `is_admin_channel`;
\ No newline at end of file
diff --git a/code/controllers/subsystems/news.dm b/code/controllers/subsystems/news.dm
index 619ac15ca58..ca081bd1134 100644
--- a/code/controllers/subsystems/news.dm
+++ b/code/controllers/subsystems/news.dm
@@ -40,7 +40,7 @@
catch(var/exception/ec)
log_debug("SSnews: Error when loading channel: [ec]")
continue
- var/DBQuery/news_query = dbcon.NewQuery("SELECT body, author, is_admin_message, message_type, time_stamp FROM ss13_news_stories WHERE deleted_at IS NULL AND channel_id = :channel_id: ORDER BY created_at DESC")
+ var/DBQuery/news_query = dbcon.NewQuery("SELECT body, author, is_admin_message, message_type, ic_timestamp, url FROM ss13_news_stories WHERE deleted_at IS NULL AND channel_id = :channel_id: AND publish_at < NOW() AND (publish_until > NOW() OR publish_until IS NULL) AND approved_at IS NOT NULL ORDER BY publish_at DESC")
news_query.Execute(list("channel_id" = channel_query.item[1]))
while(news_query.NextRow())
CHECK_TICK
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 69261101f69..996c4659cda 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -133,11 +133,6 @@ var/list/sacrificed = list()
target.hallucination = min(target.hallucination, 500)
return 0
- //If you dont have blood, blood magic doesnt work on you
- if(target.is_mechanical())
- attacker << "You sense that your powers can not effect them."
- return 0
-
target.take_overall_damage(0, rand(5, 20)) // You dirty resister cannot handle the damage to your mind. Easily. - even cultists who accept right away should experience some effects
// Resist messages go!
if(initial_message) //don't do this stuff right away, only if they resist or hesitate.
@@ -181,11 +176,51 @@ var/list/sacrificed = list()
var/choice = alert(target,"Do you want to join the cult?","Submit to Nar'Sie","Resist","Submit")
waiting_for_input[target] = 0
if(choice == "Submit") //choosing 'Resist' does nothing of course.
- cult.add_antagonist(target.mind)
- converting -= target
- target.hallucination = 0 //sudden clarity
- playsound(target, 'sound/effects/bloodcult.ogg', 100, 1)
+ if(!target.is_mechanical())
+ cult.add_antagonist(target.mind)
+ converting -= target
+ target.hallucination = 0 //sudden clarity
+ playsound(target, 'sound/effects/bloodcult.ogg', 100, 1)
+ else
+ converting -= target
+ //If we are dealing with a IPC then ask the caster what construct they want
+ var/construct_class = alert(attacker, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
+ playsound(target, 'sound/effects/bloodcult.ogg', 100, 1)
+
+ //Spawn some remains
+ new target.species.remains_type(target.loc) //spawns a skeleton based on the species remain type
+ target.invisibility = 101
+ var/atom/movable/overlay/animation = new /atom/movable/overlay( target.loc )
+ animation.icon_state = "blank"
+ animation.icon = 'icons/mob/mob.dmi'
+ animation.master = target
+ flick("dust-h", animation)
+ qdel(animation)
+
+ //Spawn the selected construct
+ switch(construct_class)
+ if("Juggernaut")
+ var/mob/living/simple_animal/construct/armoured/Z = new /mob/living/simple_animal/construct/armoured (get_turf(target.loc))
+ Z.key = target.key
+ qdel(target)
+ cult.add_antagonist(Z.mind)
+ Z << "You are playing a Juggernaut. Though slow, you can withstand extreme punishment, and rip apart enemies and walls alike."
+ Z << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs."
+ if("Wraith")
+ var/mob/living/simple_animal/construct/wraith/Z = new /mob/living/simple_animal/construct/wraith (get_turf(target.loc))
+ Z.key = target.key
+ qdel(target)
+ cult.add_antagonist(Z.mind)
+ Z << "You are playing a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls."
+ Z << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs."
+ if("Artificer")
+ var/mob/living/simple_animal/construct/builder/Z = new /mob/living/simple_animal/construct/builder (get_turf(target.loc))
+ Z.key = target.key
+ qdel(target)
+ cult.add_antagonist(Z.mind)
+ Z << "You are playing an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, repair allied constructs (by clicking on them), and even create new constructs"
+ Z << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs."
sleep(100) //proc once every 10 seconds
return 1
@@ -1064,7 +1099,6 @@ var/list/sacrificed = list()
/////////////////////////////////////////TWENTY-FIFTH RUNE
/obj/effect/rune/proc/armor(var/mob/living/user)
-
if(istype(src,/obj/effect/rune))
user.say("N'ath reth sh'yro eth d[pick("'","`")]raggathnor!")
else
diff --git a/code/game/jobs/job/civilian_chaplain.dm b/code/game/jobs/job/civilian_chaplain.dm
index e9ba159c345..4427d8740d9 100644
--- a/code/game/jobs/job/civilian_chaplain.dm
+++ b/code/game/jobs/job/civilian_chaplain.dm
@@ -20,6 +20,7 @@
var/obj/item/weapon/storage/bible/B = new /obj/item/weapon/storage/bible(H) //BS12 EDIT
H.equip_to_slot_or_del(B, slot_l_hand)
+ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear)
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/chaplain(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/device/pda/chaplain(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes)
diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm
index 1534f1827b6..096fa59262f 100644
--- a/code/game/machinery/OpTable.dm
+++ b/code/game/machinery/OpTable.dm
@@ -82,7 +82,7 @@
if (C == user)
user.visible_message("[user] climbs on \the [src].","You climb on \the [src].")
else
- visible_message("\The [C] has been laid on \the [src] by [user].", 3)
+ visible_message("\The [C] has been laid on \the [src] by [user].")
if (C.client)
C.client.perspective = EYE_PERSPECTIVE
C.client.eye = src
diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm
index 3440c0dd1f0..cfdd0ea3eaa 100644
--- a/code/game/objects/items/weapons/manuals.dm
+++ b/code/game/objects/items/weapons/manuals.dm
@@ -1367,35 +1367,4 @@
Remember; once you have been afflicted with brain trauma you are over four times as likely to suffer it again! Keep your patient's best interests at heart.