Skip to content

Commit

Permalink
[PORT FEAT] Borg Hats (#497)
Browse files Browse the repository at this point in the history
<!-- Пишите **НИЖЕ** заголовков и **ВЫШЕ** комментариев, иначе что то
может пойти не так. -->
<!-- Вы можете прочитать Contributing.MD, если хотите узнать больше. -->

Порт моего старого ПРа:
ss220-space/Paradise#1318

## Что этот PR делает
На силиконов теперь можно надеть шапки.

Изменения:
- У каждого силикона и модуля имеются свои оффсеты и правила
- Хуманизированные борги могут носить шлема
- Хуманизированные борги с встроенными шляпами - не могут носить шляпы.
- Головной убор надевается в слот головы
- HELP-intent с шляпой в руке - надевает её на силикона.
- GRAB-intent с пустой рукой - снимает с силикона шляпу.
- ГИБ и деконструкт - роняет головной убор
- Смена модуля - изменяет ОФФсет под текущий модуль
- Готовые борги с модулями (синди, дезсквад, дестроеры) сразу имеют
нужные оффсеты и правила.
- Дроны могут носить головной убор
- ИИ может носить не-шлемовые головные уборы
- Новые силиконы сразу корректно инициализируются, из-за чего можно
создать сразу боргов со шляпами, если то требуется.
- Кувырок силикона снимает с него шляпу.

ПИИ ущемлены и не умеют носить шапки, так как у них имеются разные
состояния анимации, а мне лень ими заниматься.

## Почему это хорошо для игры
Ассистенты и экипаж получают возможности угнетать силиконов, у которых
нет ручек снять шляпы.

Портируем нашу возможность надевать на боргов шапки.
Я накодил это кучу лет назад, я и портировал. Уот так уот.

## Изображения изменений
<!-- Если вы не меняли карту или спрайты, можете опустить эту секцию.
Если хотите, можете вставить видео. -->
### Разные модули:

![image](https://user-images.githubusercontent.com/41479614/188896565-b8f47a7b-9d65-46f5-aab9-00bd6eb394ef.png)
Скриншот чутка устарел. Коробочные борги во второй колонне были
поправлены.

### Написание в чате производимых действий

![image](https://user-images.githubusercontent.com/41479614/188897764-20f0f8b5-6d59-4012-b0c2-6ac91c3cbf5a.png)



## Тестирование

![image](https://github.com/ss220club/Paradise-SS220/assets/41479614/f04c4526-c3c2-48b5-a8cf-801668d1ce4a)

![image](https://github.com/ss220club/Paradise-SS220/assets/41479614/09f9ad5f-b7ee-4a45-8d03-9b888f9e118d)

## Changelog

:cl:
add: Силиконы могут носить шляпы
add: Обработка шляп, индивидуальные оффсеты для разных модулей боргов,
установка шляпы хелп-интентом, снятие шляпы граб-интентом, разбор/гиб
сбрасывают шляпу
add: Кувырок силикона снимает с него шляпу
/:cl:

<!-- Оба :cl:'а должны быть на месте, что-бы чейнджлог работал! Вы
можете написать свой ник справа от первого :cl:, если хотите. Иначе
будет использован ваш ник на ГитХабе. -->
<!-- Вы можете использовать несколько записей с одинаковым префиксом
(Они используются только для иконки в игре) и удалить ненужные. Помните,
что чейнджлог должен быть понятен обычным игроком. -->
<!-- Если чейнджлог не влияет на игроков(например, это рефактор), вы
можете исключить всю секцию. -->
  • Loading branch information
PhantornRU authored and Furrior committed Oct 22, 2023
1 parent 14aaab4 commit 832a16c
Show file tree
Hide file tree
Showing 5 changed files with 328 additions and 0 deletions.
1 change: 1 addition & 0 deletions modular_ss220/modular_ss220.dme
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "vending/vending.dme"
#include "wire_splicing/wiresplicing.dme"
#include "silicons/_silicons.dme"
#include "silicon_hats/_silicon_hats.dme"

// --- MISC --- //
#include "administration/_administration.dme"
Expand Down
4 changes: 4 additions & 0 deletions modular_ss220/silicon_hats/_silicon_hats.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/datum/modpack/silicon_hats
name = "Silicon Hats"
desc = "На силиконов можно надеть шапочки."
author = "PhantomRU"
4 changes: 4 additions & 0 deletions modular_ss220/silicon_hats/_silicon_hats.dme
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include "_silicon_hats.dm"

#include "code/silicon_hats.dm"
#include "code/silicon_interactions.dm"
218 changes: 218 additions & 0 deletions modular_ss220/silicon_hats/code/silicon_hats.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
/mob/living/silicon
var/obj/item/inventory_head

var/hat_offset_y = -3
var/is_centered = FALSE // центрирован ли синтетик. Если нет, то шляпа будет растянута

var/list/blacklisted_hats = list( // Запрещенные шляпы на ношение для боргов с большими головами
/obj/item/clothing/head/helmet,
/obj/item/clothing/head/welding,
/obj/item/clothing/head/snowman,
/obj/item/clothing/head/bio_hood,
/obj/item/clothing/head/bomb_hood,
/obj/item/clothing/head/blob,
/obj/item/clothing/head/chicken,
/obj/item/clothing/head/corgi,
/obj/item/clothing/head/cueball,
/obj/item/clothing/head/hardhat/pumpkinhead,
/obj/item/clothing/head/radiation,
/obj/item/clothing/head/papersack,
/obj/item/clothing/head/human_head,
/obj/item/clothing/head/kitty,
/obj/item/clothing/head/hardhat/reindeer,
/obj/item/clothing/head/cardborg,
)

var/hat_icon_file = 'icons/mob/clothing/head.dmi'
var/hat_icon_state
var/hat_alpha
var/hat_color

var/can_be_hatted = FALSE
var/can_wear_blacklisted_hats = FALSE

/mob/living/silicon/robot/drone
hat_offset_y = -15
is_centered = TRUE
can_be_hatted = TRUE
can_wear_blacklisted_hats = TRUE

/mob/living/silicon/ai
hat_offset_y = 3
is_centered = TRUE
can_be_hatted = TRUE

/mob/living/silicon/robot/proc/robot_module_hat_offset(module)
switch(module)
// хуманоидные броботы с шляпами
if("Engineering", "Miner_old", "JanBot2", "Medbot", "engineerrobot", "maximillion", "secborg", "Hydrobot")
can_be_hatted = FALSE
hat_offset_y = -1
if("Noble-CLN", "Noble-SRV", "Noble-DIG", "Noble-MED", "Noble-SEC", "Noble-ENG", "Noble-STD") //Высотой: 32 пикселя
can_be_hatted = TRUE
can_wear_blacklisted_hats = TRUE
hat_offset_y = 4
if("droid-medical") // Высотой: 32 пикселя
can_be_hatted = TRUE
can_wear_blacklisted_hats = TRUE
hat_offset_y = 4
if("droid-miner", "mk2", "mk3") // Высотой: 32 большая голова, шарообразные
can_be_hatted = TRUE
is_centered = TRUE
hat_offset_y = 3
if("bloodhound", "nano_bloodhound", "syndie_bloodhound", "ertgamma")//Высотой: 31
can_be_hatted = TRUE
hat_offset_y = 1
if("Cricket-SEC", "Cricket-MEDI", "Cricket-JANI", "Cricket-ENGI", "Cricket-MINE", "Cricket-SERV") //Высотой: 31
can_be_hatted = TRUE
hat_offset_y = 2
if("droidcombat-shield", "droidcombat") // Высотой: 31
can_be_hatted = TRUE
hat_alpha = 255
hat_offset_y = 2
if("droidcombat-roll")
can_be_hatted = TRUE
hat_alpha = 0
hat_offset_y = 2
if("syndi-medi", "surgeon", "toiletbot") // Высотой: 30
can_be_hatted = TRUE
is_centered = TRUE
hat_offset_y = 1
if("Security", "janitorrobot", "medicalrobot") // Высотой: 29
can_be_hatted = TRUE
is_centered = TRUE
can_wear_blacklisted_hats = TRUE
hat_offset_y = -1
if("Brobot", "Service", "robot+o+c", "robot_old", "securityrobot", //Высотой: 28
"rowtree-engineering", "rowtree-lucy", "rowtree-medical", "rowtree-security") //Бабоботы
can_be_hatted = TRUE
is_centered = TRUE
can_wear_blacklisted_hats = TRUE
hat_offset_y = -1
if("Miner", "lavaland") // Высотой: 27
can_be_hatted = TRUE
hat_offset_y = -1
if("robot", "Standard", "Standard-Secy", "Standard-Medi", "Standard-Engi",
"Standard-Jani", "Standard-Serv", "Standard-Mine", "xenoborg-state-a") //Высотой: 26
can_be_hatted = TRUE
hat_offset_y = -3
if("droid") // Высотой: 25
can_be_hatted = TRUE
is_centered = TRUE
can_wear_blacklisted_hats = TRUE
hat_offset_y = -3
if("landmate", "syndi-engi") // Высотой: 24 пикселя макушка
can_be_hatted = TRUE
hat_offset_y = -3
if("mopgearrex") // Высотой: 22
can_be_hatted = TRUE
hat_offset_y = -6

if(inventory_head)
if (!can_be_hatted)
remove_from_head(usr)
return
if (!can_wear_blacklisted_hats && is_type_in_list(inventory_head, blacklisted_hats))
remove_from_head(usr)
return

/mob/living/silicon/proc/hat_icons()
if(inventory_head)
overlays += get_hat_overlay()

/mob/living/silicon/regenerate_icons()
overlays.Cut()
..()

if(inventory_head)
var/image/head_icon

if(inventory_head.icon_override) // Для модульных шапок
hat_icon_file = inventory_head.icon_override
if(!hat_icon_state)
hat_icon_state = inventory_head.icon_state
if(!hat_alpha)
hat_alpha = inventory_head.alpha
if(!hat_color)
hat_color = inventory_head.color

head_icon = get_hat_overlay()

add_overlay(head_icon)

/mob/living/silicon/proc/get_hat_overlay()
if(hat_icon_file && hat_icon_state)
var/image/borgI = image(hat_icon_file, hat_icon_state)
borgI.alpha = hat_alpha
borgI.color = hat_color
borgI.pixel_y = hat_offset_y
if (!is_centered)
borgI.transform = matrix(1.125, 0, 0.5, 0, 1, 0)
return borgI

/mob/living/silicon/proc/place_on_head(obj/item/item_to_add, mob/user)
if(!item_to_add)
user.visible_message(span_notice("[user] похлопывает по голове [src]."), span_notice("Вы положили руку на голову [src]."))
if(flags_2 & HOLOGRAM_2)
return FALSE
return FALSE

if(!istype(item_to_add, /obj/item/clothing/head/))
to_chat(user, span_warning("[item_to_add] нельзя надеть на голову [src]!"))
return FALSE

if(!can_be_hatted)
to_chat(user, span_warning("[item_to_add] нельзя надеть на голову [src]! Похоже у него уже есть встроенная шляпа."))
return FALSE

if(inventory_head)
if(user)
to_chat(user, span_warning("Нельзя надеть больше одного головного убора на голову [src]!"))
return FALSE

if(user && !user.unEquip(item_to_add))
to_chat(user, span_warning("[item_to_add] застрял в ваших руках, вы не можете его надеть на голову [src]!"))
return FALSE

if (!can_wear_blacklisted_hats && is_type_in_list(item_to_add, blacklisted_hats))
to_chat(user, span_warning("[item_to_add] не помещается на голову [src]!"))
return FALSE

user.visible_message(span_notice("[user] надевает [item_to_add] на голову [real_name]."),
span_notice("Вы надеваете [item_to_add] на голову [real_name]."),
span_italics("Вы слышите как что-то нацепили."))
item_to_add.forceMove(src)
inventory_head = item_to_add
regenerate_icons()

return TRUE

/mob/living/silicon/proc/remove_from_head(mob/user)
if(inventory_head)
if(inventory_head.flags & NODROP)
to_chat(user, span_warning("[inventory_head.name] застрял на головном корпусе [src]! Его невозможно снять!"))
return TRUE

to_chat(user, span_warning("Вы сняли [inventory_head.name] с головного корпуса [src]."))
user.put_in_hands(inventory_head)

null_hat()

regenerate_icons()
else
to_chat(user, span_warning("На головном корпусе [src] нет головного убора!"))
return FALSE

return TRUE

/mob/living/silicon/proc/drop_hat()
if(inventory_head)
unEquip(inventory_head)
null_hat()
regenerate_icons()

/mob/living/silicon/proc/null_hat()
inventory_head = null
hat_icon_state = null
hat_alpha = null
hat_color = null
101 changes: 101 additions & 0 deletions modular_ss220/silicon_hats/code/silicon_interactions.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/mob/living/silicon/robot/update_icons()
. = ..()
hat_icons()

/mob/living/silicon/robot/drone/update_icons()
. = ..()
hat_icons()

/mob/living/silicon/death(gibbed)
if(gibbed)
drop_hat()
. = ..()

/mob/living/silicon/robot/deconstruct()
drop_hat()
. = ..()

/mob/living/silicon/robot/get_module_sprites(selected_module)
. = ..()
robot_module_hat_offset(icon_state)

/mob/living/silicon/grabbedby(mob/living/user)
remove_from_head(user)

// Если вдруг кто-то захочет сразу спавнить боргов с шапками
/mob/living/silicon/Initialize(mapload)
. = ..()
regenerate_icons()

// Для уже готовых спавнов боевых боргов
/mob/living/silicon/robot/Initialize(mapload)
. = ..()
robot_module_hat_offset(icon_state)

/mob/living/silicon/robot/initialize_module(selected_module, selected_sprite, list/module_sprites)
. = ..()
robot_module_hat_offset(icon_state)

/datum/emote/flip/run_emote(mob/user, params, type_override, intentional)
. = ..()
if(isrobot(user))
var/mob/living/silicon/robot/borg = user
message = "кувырком опрокинул шляпу!"
borg.drop_hat()

/mob/living/silicon/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/clothing/head) && user.a_intent == INTENT_HELP)
place_on_head(user.get_active_hand(), user)
return TRUE
. = ..()

/mob/living/silicon/Topic(href, href_list)
if(..())
return TRUE

if(!(iscarbon(usr) || usr.incapacitated() || !Adjacent(usr)))
usr << browse(null, "window=mob[UID()]")
usr.unset_machine()
return FALSE

if (!can_be_hatted)
return FALSE

if(href_list["remove_inv"])
var/remove_from = href_list["remove_inv"]
switch(remove_from)
if("head")
remove_from_head(usr)
show_inv(usr)

else if(href_list["add_inv"])
var/add_to = href_list["add_inv"]
switch(add_to)
if("head")
place_on_head(usr.get_active_hand(), usr)
show_inv(usr)

if(usr != src)
return TRUE

/mob/living/silicon/show_inv(mob/user)
if(user.incapacitated() || !Adjacent(user))
return FALSE
user.set_machine(src)

var/dat = {"<meta charset="UTF-8"><div align='center'><b>Inventory of [name]</b></div><p>"}
dat += "<br><B>Head:</B> <A href='?src=[UID()];[inventory_head ? "remove_inv=head'>[inventory_head]" : "add_inv=head'>Nothing"]</A>"

var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 500)
popup.set_content(dat)
popup.open()

/mob/living/silicon/robot/examine(mob/user)
. = ..()
if(inventory_head)
. += "\nНосит [bicon(inventory_head)] [inventory_head.name].\n"

/mob/living/silicon/ai/examine(mob/user)
. = ..()
if(inventory_head)
. += "\nНа корпусе расположился [bicon(inventory_head)] [inventory_head.name].\n"

0 comments on commit 832a16c

Please sign in to comment.