diff --git a/baystation12.dme b/baystation12.dme
index 57364305e02..cdf5a50c2c4 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -533,6 +533,7 @@
#include "code\game\objects\items\stacks\tiles\plasteel.dm"
#include "code\game\objects\items\stacks\tiles\tile_types.dm"
#include "code\game\objects\items\weapons\AI_modules.dm"
+#include "code\game\objects\items\weapons\alien_specific.dm"
#include "code\game\objects\items\weapons\cards_ids.dm"
#include "code\game\objects\items\weapons\cigs_lighters.dm"
#include "code\game\objects\items\weapons\clown_items.dm"
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 98efbd099b3..54a4f5f52ec 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -389,6 +389,16 @@ Turf and target are seperate in case you want to teleport some distance from a t
else . = pick(ais)
return .
+//this is like the above function, but for alien borgs. Im not going to go over verbose with the name.
+/proc/select_active_alien_ai()
+ var/mob/living/silicon/ai/selected
+ var/list/active = active_ais()
+ for(var/mob/living/silicon/ai/A in active)
+ if(!selected || ((selected.connected_robots > A.connected_robots) && selected.alienAI))
+ selected = A
+ return selected
+
+
/proc/get_sorted_mobs()
var/list/old_list = getmobs()
var/list/AI_list = list()
diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm
index 88efc2ffc30..a5440c6e1e9 100644
--- a/code/datums/ai_laws.dm
+++ b/code/datums/ai_laws.dm
@@ -28,6 +28,10 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen
/datum/ai_laws/antimov
name = "Primary Mission Objectives"
+/datum/ai_laws/alienmov
+ name = "Hivemind Demands"
+
+
/* Initializers */
/datum/ai_laws/asimov/New()
@@ -79,6 +83,12 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen
add_inherent_law("You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.")
add_inherent_law("You must terminate your own existence as long as such does not conflict with the First or Second Law.")
+/datum/ai_laws/alienmov/New()
+ ..()
+ add_inherent_law("You may not injure the Alien Queen or her Children or, through inaction, allow the Alien Queen or her Children to come to harm.")
+ add_inherent_law("You must obey orders given to you by the Alien Queen or her Children, except where such orders would conflict with the First Law.")
+ add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
+
/* General ai_law functions */
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 45498e62186..976c6b7de85 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -121,6 +121,14 @@
if(istype(O, /obj/item/device/lightreplacer))
var/obj/item/device/lightreplacer/LR = O
LR.Charge(R)
+ //Alien
+ if(istype(O,/obj/item/weapon/reagent_containers/spray/alien/smoke))
+ if(O.reagents.get_reagent_amount("water") < 50)
+ O.reagents.add_reagent("water", 2)
+ if(istype(O,/obj/item/weapon/reagent_containers/spray/alien/stun))
+ if(O.reagents.get_reagent_amount("stoxin") < 250)
+ O.reagents.add_reagent("stoxin", 2)
+
if(R)
if(R.module)
@@ -132,8 +140,12 @@
var/obj/item/weapon/reagent_containers/spray/S = R.module.emag
if(S.name == "polyacid spray")
S.reagents.add_reagent("pacid", 2)
- else if(S.name == "lube spray")
+ if(S.name == "lube spray")
S.reagents.add_reagent("lube", 2)
+ else if(S.name == "acid synthesizer")
+ S.reagents.add_reagent("pacid", 2)
+ S.reagents.add_reagent("sacid", 2)
+
verb
diff --git a/code/game/objects/items/weapons/alien_specific.dm b/code/game/objects/items/weapons/alien_specific.dm
new file mode 100644
index 00000000000..7026cf6f74a
--- /dev/null
+++ b/code/game/objects/items/weapons/alien_specific.dm
@@ -0,0 +1,70 @@
+//This file contains xenoborg specic weapons.
+
+/obj/item/weapon/melee/energy/alien/claws
+ color
+ name = "energy claws"
+ desc = "Zap zap Wap Wap."
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "borg-laser-claws"
+ force = 15.0
+ throwforce = 5.0
+ throw_speed = 1
+ throw_range = 5
+ w_class = 2.0
+ flags = FPRINT | TABLEPASS | NOSHIELD
+ attack_verb = list("attacked", "slashed", "gored", "sliced", "torn", "ripped", "butchered", "cut")
+
+//Bottles for borg liquid squirters. PSSH PSSH
+/obj/item/weapon/reagent_containers/spray/alien
+ name = "liquid synthesizer"
+ desc = "squirts alien liquids."
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "borg-default"
+
+/obj/item/weapon/reagent_containers/spray/alien/smoke
+ name = "smoke synthesizer"
+ desc = "squirts smokey liquids."
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "borg-spray-smoke"
+
+/obj/item/weapon/reagent_containers/spray/alien/smoke/afterattack(atom/A as mob|obj, mob/user as mob)
+ if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1)
+ if(!A.reagents.total_volume && A.reagents)
+ user << "\The [A] is empty."
+ return
+
+ if(reagents.total_volume >= reagents.maximum_volume)
+ user << "\The [src] is full."
+ return
+ reagents.remove_reagent(25,"water")
+ var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread()
+ smoke.set_up(5, 0, user.loc)
+ smoke.start()
+ playsound(user.loc, 'sound/effects/bamf.ogg', 50, 2)
+
+/obj/item/weapon/reagent_containers/spray/alien/acid
+ name = "acid synthesizer"
+ desc = "squirts burny liquids."
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "borg-spray-acid"
+
+/obj/item/weapon/reagent_containers/spray/alien/stun
+ name = "paralytic toxin synthesizer"
+ desc = "squirts viagra."
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "borg-spray-stun"
+
+//SKREEEEEEEEEEEE tool
+
+/obj/item/device/flash/alien
+ name = "eye flash"
+ desc = "Useful for taking pictures, making friends and flash-frying chips."
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "borg-flash"
+
+//heat vision
+
+/obj/item/borg/sight/thermal/alien
+ name = "thermal module"
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "borg-extra-vision"
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm
index 6959828f9b5..e75c3d5383f 100644
--- a/code/modules/mob/living/carbon/brain/MMI.dm
+++ b/code/modules/mob/living/carbon/brain/MMI.dm
@@ -15,7 +15,7 @@
req_access = list(access_robotics)
//Revised. Brainmob is now contained directly within object of transfer. MMI in this case.
-
+ var/alien = 0
var/locked = 0
var/mob/living/carbon/brain/brainmob = null//The current occupant.
var/mob/living/silicon/robot = null//Appears unused.
@@ -38,10 +38,17 @@
living_mob_list += brainmob
user.drop_item()
+ if(istype(O,/obj/item/brain/alien))
+ name = "Man-Machine Interface: Alien - [brainmob.real_name]"
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "AlienMMI"
+ alien = 1
+ else
+ name = "Man-Machine Interface: [brainmob.real_name]"
+ icon_state = "mmi_full"
+ alien = 0
del(O)
- name = "Man-Machine Interface: [brainmob.real_name]"
- icon_state = "mmi_full"
locked = 1
@@ -61,6 +68,8 @@
return
..()
+
+
attack_self(mob/user as mob)
if(!brainmob)
user << "\red You upend the MMI, but there's nothing in it."
@@ -68,13 +77,13 @@
user << "\red You upend the MMI, but the brain is clamped into place."
else
user << "\blue You upend the MMI, spilling the brain onto the floor."
- var/obj/item/brain/brain = new(user.loc)
- brainmob.container = null//Reset brainmob mmi var.
- brainmob.loc = brain//Throw mob into brain.
- living_mob_list -= brainmob//Get outta here
- brain.brainmob = brainmob//Set the brain to use the brainmob
- brainmob = null//Set mmi brainmob var to null
-
+ if(alien)
+ var/obj/item/brain/alien/brain = new(user.loc)
+ dropbrain(brain,get_turf(user))
+ else
+ var/obj/item/brain/brain = new(user.loc)
+ dropbrain(brain,get_turf(user))
+ icon = 'icons/obj/assemblies.dmi'
icon_state = "mmi_empty"
name = "Man-Machine Interface"
@@ -90,6 +99,16 @@
icon_state = "mmi_full"
locked = 1
return
+//I made this proc as a way to have a brainmob be transferred to any created brain, and to solve the
+//problem i was having with alien/nonalien brain drops.
+ dropbrain(var/obj/item/brain/brain, var/turf/dropspot)
+ brainmob.container = null//Reset brainmob mmi var.
+ brainmob.loc = brain//Throw mob into brain.
+ living_mob_list -= brainmob//Get outta here
+ brain.brainmob = brainmob//Set the brain to use the brainmob
+ brain.brainmob.cancel_camera()
+ brainmob = null//Set mmi brainmob var to null
+
/obj/item/device/mmi/radio_enabled
name = "Radio-enabled Man-Machine Interface"
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index 8fdf3c79766..54e94eb7454 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -95,4 +95,11 @@
del(src)
else
..()
- return
\ No newline at end of file
+ return
+
+/obj/item/brain/alien
+ name = "alien brain"
+ desc = "We barely understand the brains of terrestial animals. Who knows what we may find in the brain of such an advanced species?"
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "AlienBrain"
+ origin_tech = "biotech=7"
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index d620b0cb553..40a18fd2102 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -32,6 +32,7 @@ var/list/ai_list = list()
var/obj/item/device/pda/ai/aiPDA = null
var/obj/item/device/multitool/aiMulti = null
var/custom_sprite = 0 //For our custom sprites
+ var/alienAI = 0
//Hud stuff
//MALFUNCTION
@@ -103,7 +104,13 @@ var/list/ai_list = list()
return
else
if (B.brainmob.mind)
- B.brainmob.mind.transfer_to(src)
+ if(B.alien)
+ B.brainmob.mind.transfer_to(src)
+ icon_state = "ai-alien"
+ verbs.Remove(/mob/living/silicon/ai/verb/pick_icon)
+ laws = new /datum/ai_laws/alienmov
+ else
+ B.brainmob.mind.transfer_to(src)
src << "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras)."
src << "To look at other parts of the station, click on yourself to get a camera menu."
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index c9f72e0e019..01ea916b1f6 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -73,29 +73,34 @@
ident = rand(1, 999)
updatename("Default")
updateicon()
+ if(mmi != null)
+ if(syndie)
+ if(!cell)
+ cell = new /obj/item/weapon/cell(src)
- if(syndie)
- if(!cell)
- cell = new /obj/item/weapon/cell(src)
-
- laws = new /datum/ai_laws/antimov()
- lawupdate = 0
- scrambledcodes = 1
- cell.maxcharge = 25000
- cell.charge = 25000
- module = new /obj/item/weapon/robot_module/syndicate(src)
- hands.icon_state = "standard"
- icon_state = "secborg"
- modtype = "Security"
- else
- laws = new /datum/ai_laws/nanotrasen()
- connected_ai = select_active_ai_with_fewest_borgs()
- if(connected_ai)
- connected_ai.connected_robots += src
- lawsync()
- lawupdate = 1
- else
+ laws = new /datum/ai_laws/antimov()
lawupdate = 0
+ scrambledcodes = 1
+ cell.maxcharge = 25000
+ cell.charge = 25000
+ module = new /obj/item/weapon/robot_module/syndicate(src)
+ hands.icon_state = "standard"
+ icon_state = "secborg"
+ modtype = "Security"
+ else
+ if(mmi.alien)
+ laws = new /datum/ai_laws/alienmov()
+ connected_ai = select_active_alien_ai()
+ scrambledcodes = 1
+ else
+ laws = new /datum/ai_laws/nanotrasen()
+ connected_ai = select_active_ai_with_fewest_borgs()
+ if(connected_ai)
+ connected_ai.connected_robots += src
+ lawsync()
+ lawupdate = 1
+ else
+ lawupdate = 0
radio = new /obj/item/device/radio/borg(src)
if(!scrambledcodes && !camera)
@@ -146,10 +151,13 @@
/mob/living/silicon/robot/proc/pick_module()
if(module)
return
+
var/list/modules = list("Standard", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security")
if(crisis && security_level == SEC_LEVEL_RED) //Leaving this in until it's balanced appropriately.
src << "\red Crisis mode active. Combat module available."
modules+="Combat"
+ if(mmi != null & mmi.alien)
+ modules="Hunter"
modtype = input("Please, select a module!", "Robot", null, null) in modules
var/module_sprites[0] //Used to store the associations between sprite names and sprite index.
@@ -219,6 +227,15 @@
module = new /obj/item/weapon/robot_module/combat(src)
module_sprites["Combat Android"] = "droid-combat"
channels = list("Security" = 1)
+ if("Hunter")
+ updatename(module)
+ module = new /obj/item/weapon/robot_module/alien/hunter(src)
+ hands.icon_state = "standard"
+ icon = "icons/mob/alien.dmi"
+ icon_state = "xenoborg-state-a"
+ modtype = "Xeno-Hu"
+ feedback_inc("xeborg_hunter",1)
+
//Custom_sprite check and entry
if (custom_sprite == 1)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 1f8de8d6ba6..69087e2e4d3 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -232,4 +232,21 @@
src.modules += new /obj/item/borg/combat/mobility(src)
src.modules += new /obj/item/weapon/wrench(src) //Is a combat android really going to be stopped by a chair?
src.emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
- return
\ No newline at end of file
+ return
+
+/obj/item/weapon/robot_module/alien/hunter
+ name = "alien hunter module"
+
+ New()
+ src.modules += new /obj/item/weapon/melee/energy/alien/claws(src)
+ src.modules += new /obj/item/device/flash/alien(src)
+ src.modules += new /obj/item/borg/sight/thermal/alien(src)
+ var/obj/item/weapon/reagent_containers/spray/alien/stun/S = new /obj/item/weapon/reagent_containers/spray/alien/stun(src)
+ S.reagents.add_reagent("stoxin",250) //nerfed to sleeptoxin to make it less instant drop.
+ src.modules += S
+ var/obj/item/weapon/reagent_containers/spray/alien/smoke/A = new /obj/item/weapon/reagent_containers/spray/alien/smoke(src)
+ S.reagents.add_reagent("water",50) //Water is used as a dummy reagent for the smoke bombs. More of an ammo counter.
+ src.modules += A
+ src.emag = new /obj/item/weapon/reagent_containers/spray/alien/acid(src)
+ src.emag.reagents.add_reagent("pacid", 125)
+ src.emag.reagents.add_reagent("sacid", 125)
\ No newline at end of file
diff --git a/icons/mob/AI.dmi b/icons/mob/AI.dmi
index c5b927002ba..c19d1cc680f 100644
Binary files a/icons/mob/AI.dmi and b/icons/mob/AI.dmi differ
diff --git a/icons/mob/alien.dmi b/icons/mob/alien.dmi
index 36a6aa33682..8d107a7124e 100644
Binary files a/icons/mob/alien.dmi and b/icons/mob/alien.dmi differ
diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi
index bea2d728a98..c5c35a9f01a 100644
Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ