Merge pull request #6705 from davipatury/crafting-ui

Personal Crafting Nano-UI-ification
This commit is contained in:
Crazy Lemon
2017-03-21 18:00:34 -07:00
committed by GitHub
10 changed files with 311 additions and 83 deletions
+76 -79
View File
@@ -2,6 +2,8 @@
var/busy
var/viewing_category = 1 //typical powergamer starting on the Weapons tab
var/list/categories = list(CAT_WEAPON,CAT_AMMO,CAT_ROBOT,CAT_FOOD,CAT_MISC,CAT_PRIMAL)
var/display_craftable_only = FALSE
var/display_compact = TRUE
@@ -34,8 +36,8 @@
else
continue
return 0
for(var/A in R.chem_catalists)
if(contents[A] < R.chem_catalists[A])
for(var/A in R.chem_catalysts)
if(contents[A] < R.chem_catalysts[A])
return 0
return 1
@@ -225,68 +227,70 @@
Deletion.Cut(Deletion.len)
qdel(DL)
/datum/personal_crafting/proc/craft(mob/user)
if(user.incapacitated() || user.lying || istype(user.loc, /obj/mecha))
return
/datum/personal_crafting/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, datum/topic_state/state = not_incapacitated_turf_state)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "personal_crafting.tmpl", "Crafting Menu", 700, 800, state = state)
ui.open()
/datum/personal_crafting/ui_data(mob/user)
var/list/data = list()
var/cur_category = categories[viewing_category]
data["busy"] = busy
data["prev_cat"] = categories[prev_cat()]
data["category"] = cur_category
data["next_cat"] = categories[next_cat()]
data["display_craftable_only"] = display_craftable_only
data["display_compact"] = display_compact
var/list/surroundings = get_surroundings(user)
var/dat = "<h3>Crafting menu</h3>"
if(busy)
dat += "<div class='statusDisplay'>Crafting in progress...</div>"
else
dat += "<A href='?src=[UID()];backwardCat=1'><--</A>"
dat += " [categories[prev_cat()]] |"
dat += " <B>[categories[viewing_category]]</B> "
dat += "| [categories[next_cat()]] "
dat += "<A href='?src=[UID()];forwardCat=1'>--></A><BR><BR>"
dat += "<div class='statusDisplay'>"
//Filter the recipes we can craft to the top
var/list/can_craft = list()
var/list/cant_craft = list()
for(var/datum/crafting_recipe/R in crafting_recipes)
if(R.category != categories[viewing_category])
continue
if(check_contents(R, surroundings))
can_craft += R
else
cant_craft += R
for(var/datum/crafting_recipe/R in can_craft)
dat += build_recipe_text(R, surroundings)
for(var/datum/crafting_recipe/R in cant_craft)
dat += build_recipe_text(R, surroundings)
dat += "</div>"
var/datum/browser/popup = new(user, "crafting", "Crafting", 500, 500)
popup.set_content(dat)
popup.open()
return
var/list/can_craft = list()
var/list/cant_craft = list()
for(var/rec in crafting_recipes)
var/datum/crafting_recipe/R = rec
if(R.category != cur_category)
continue
if(check_contents(R, surroundings))
can_craft += list(build_recipe_data(R))
else
cant_craft += list(build_recipe_data(R))
data["can_craft"] = can_craft
data["cant_craft"] = cant_craft
return data
/datum/personal_crafting/Topic(href, href_list)
if(usr.stat || usr.lying)
if(..())
return
if(href_list["make"])
var/datum/crafting_recipe/TR = locate(href_list["make"])
busy = 1
craft(usr)
nanomanager.update_uis(src)
var/fail_msg = construct_item(usr, TR)
if(!fail_msg)
usr << "<span class='notice'>[TR.name] constructed.</span>"
to_chat(usr, "<span class='notice'>[TR.name] constructed.</span>")
else
usr << "<span class ='warning'>Construction failed[fail_msg]</span>"
to_chat(usr, "<span class ='warning'>Construction failed[fail_msg]</span>")
busy = 0
craft(usr)
nanomanager.update_uis(src)
if(href_list["forwardCat"])
viewing_category = next_cat()
usr << "<span class='notice'>Category is now [categories[viewing_category]].</span>"
craft(usr)
to_chat(usr, "<span class='notice'>Category is now [categories[viewing_category]].</span>")
. = TRUE
if(href_list["backwardCat"])
viewing_category = prev_cat()
usr << "<span class='notice'>Category is now [categories[viewing_category]].</span>"
craft(usr)
to_chat(usr, "<span class='notice'>Category is now [categories[viewing_category]].</span>")
. = TRUE
if(href_list["toggle_recipes"])
display_craftable_only = !display_craftable_only
to_chat(usr, "<span class='notice'>You will now [display_craftable_only ? "only see recipes you can craft":"see all recipes"].</span>")
. = TRUE
if(href_list["toggle_compact"])
display_compact = !display_compact
to_chat(usr, "<span class='notice'>Crafting menu is now [display_compact? "compact" : "full size"].</span>")
. = TRUE
nanomanager.update_uis(src)
//Next works nicely with modular arithmetic
/datum/personal_crafting/proc/next_cat()
@@ -301,39 +305,32 @@
if(. <= 0)
. = categories.len
/datum/personal_crafting/proc/build_recipe_text(datum/crafting_recipe/R, list/contents)
. = ""
var/name_text = ""
/datum/personal_crafting/proc/build_recipe_data(datum/crafting_recipe/R)
var/list/data = list()
data["name"] = R.name
data["ref"] = "\ref[R]"
var/req_text = ""
var/tool_text = ""
var/catalist_text = ""
if(check_contents(R, contents))
name_text ="<A href='?src=[UID()];make=\ref[R]'>[R.name]</A>"
var/catalyst_text = ""
else
name_text = "<span class='linkOff'>[R.name]</span>"
for(var/a in R.reqs)
//We just need the name, so cheat-typecast to /atom for speed (even tho Reagents are /datum they DO have a "name" var)
//Also these are typepaths so sadly we can't just do "[a]"
var/atom/A = a
req_text += " [R.reqs[A]] [initial(A.name)],"
req_text = replacetext(req_text, ",", "", -1)
data["req_text"] = req_text
if(name_text)
for(var/A in R.reqs)
if(ispath(A, /obj))
var/obj/O = A
req_text += " [R.reqs[A]] [initial(O.name)]"
else if(ispath(A, /datum/reagent))
var/datum/reagent/RE = A
req_text += " [R.reqs[A]] [initial(RE.name)]"
for(var/a in R.chem_catalysts)
var/atom/A = a //cheat-typecast
catalyst_text += " [R.chem_catalysts[A]] [initial(A.name)],"
catalyst_text = replacetext(catalyst_text, ",", "", -1)
data["catalyst_text"] = catalyst_text
if(R.chem_catalists.len)
catalist_text += ", Catalysts:"
for(var/C in R.chem_catalists)
if(ispath(C, /datum/reagent))
var/datum/reagent/RE = C
catalist_text += " [R.chem_catalists[C]] [initial(RE.name)]"
for(var/a in R.tools)
var/atom/A = a //cheat-typecast
tool_text += " [R.tools[A]] [initial(A.name)],"
tool_text = replacetext(tool_text, ",", "", -1)
data["tool_text"] = tool_text
if(R.tools.len)
tool_text += ", Tools:"
for(var/O in R.tools)
if(ispath(O, /obj))
var/obj/T = O
tool_text += " [R.tools[O]] [initial(T.name)]"
. = "[name_text][req_text][tool_text][catalist_text]<BR>"
return data
+1 -1
View File
@@ -5,7 +5,7 @@
var/tools[] = list() //type paths of items needed but not consumed
var/time = 30 //time in deciseconds
var/parts[] = list() //type paths of items that will be placed in the result
var/chem_catalists[] = list() //like tools but for reagents
var/chem_catalysts[] = list() //like tools but for reagents
var/category = CAT_MISC // Recipe category
/datum/crafting_recipe/proc/AdjustChems(var/obj/resultobj as obj)
@@ -52,7 +52,7 @@
UpdateAppearance()
/mob/living/carbon/human/OpenCraftingMenu()
handcrafting.craft(src)
handcrafting.ui_interact(src)
/mob/living/carbon/human/prepare_data_huds()
//Update med hud images...
@@ -0,0 +1,25 @@
/**
* This state only checks if the user isn't incapacitated
**/
/var/global/datum/topic_state/not_incapacitated_state/not_incapacitated_state = new()
/**
* This state checks if the user isn't incapacitated and that their loc is a turf
**/
/var/global/datum/topic_state/not_incapacitated_state/not_incapacitated_turf_state = new(no_turfs = TRUE)
/datum/topic_state/not_incapacitated_state
var/turf_check = FALSE
/datum/topic_state/not_incapacitated_state/New(loc, no_turfs = FALSE)
..()
turf_check = no_turfs
/datum/topic_state/not_incapacitated_state/can_use_topic(src_object, mob/user)
if(user.stat)
return STATUS_CLOSE
if(user.incapacitated() || user.lying || (turf_check && !isturf(user.loc)))
return STATUS_DISABLED
return STATUS_INTERACTIVE
File diff suppressed because one or more lines are too long
+29
View File
@@ -0,0 +1,29 @@
div.display {
padding: 4px;
margin: 6px 0;
background-color: rgba(0, 0, 0, 0.33);
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
}
div.display header {
display: block;
position: relative;
width: 98.5%;
padding: 0 4px;
margin-bottom: 6px;
color: #FFFFFF;
border-bottom: 2px solid #40628a;
}
div.display header .buttonRight {
position: absolute;
bottom: 6px;
right: 4px;
}
div.display article {
display: table;
width: 100%;
border-collapse: collapse;
}
+64
View File
@@ -0,0 +1,64 @@
*[data-tooltip] {
position: relative;
&::after {
position: absolute;
display: block;
z-index: 2;
width: 250px;
padding: 10px;
transform: translateX(-50%);
visibility: hidden;
opacity: 0;
white-space: normal;
text-align: left;
content: attr(data-tooltip);
transition: all .5s;
border: 1px solid #999999;
background-color: #363636;
}
&:hover::after {
visibility: visible;
opacity: 1;
}
&.tooltipTop::after {
bottom: 100%;
left: 50%;
transform: translateX(-50%) translateY(8px);
}
&.tooltipTop:hover::after {
transform: translateX(-50%) translateY(-8px);
}
&.tooltipBottom::after {
top: 100%;
left: 50%;
transform: translateX(-50%) translateY(-8px);
}
&.tooltipBottom:hover::after {
transform: translateX(-50%) translateY(8px);
}
&.tooltipLeft::after {
top: 50%;
right: 100%;
transform: translateX(8px) translateY(-50%);
}
&.tooltipLeft:hover::after {
transform: translateX(-8px) translateY(-50%);
}
&.tooltipRight::after {
top: 50%;
left: 100%;
transform: translateX(-8px) translateY(-50%);
}
&.tooltipRight:hover::after {
transform: translateX(8px) translateY(-50%);
}
}
+2
View File
@@ -4,11 +4,13 @@
@import "_link";
@import "_color";
@import "_config";
@import "_display";
@import "_formatting";
@import "_icon";
@import "_lists";
@import "_misc";
@import "_native";
@import "_tooltip";
body {
+110
View File
@@ -0,0 +1,110 @@
<script>
{{var tooltiptext = function(req_text, catalyst_text, tool_text) { let text = ""; if(req_text){text += "REQUIREMENTS: " + req_text + " ";} if(catalyst_text){text += "CATALYSTS: " + catalyst_text + " ";} if(tool_text){text += "TOOLS: " + tool_text;}return text;};}}
</script>
<div class='display'>
<header><h3>{{:data.category}}</h3></header>
<article>
<div class='item'>
{{:helper.link(data.prev_cat, 'arrow-left', {'backwardCat': 1})}}
{{:helper.link(data.next_cat, 'arrow-right', {'forwardCat': 1})}}
{{if data.display_craftable_only}}
{{:helper.link('Showing Craftable Recipes', 'lock', {'toggle_recipes': 1})}}
{{else}}
{{:helper.link('Showing All Recipes', 'unlock', {'toggle_recipes': 1})}}
{{/if}}
{{:helper.link('Compact', data.display_compact ? 'check-square-o' : 'square-o', {'toggle_compact': 1})}}
</div>
{{if data.display_compact}}
<div class='display'>
<article>
<table style='width: 50%;'>
{{for data.can_craft}}
<tr>
<td><div class='itemLabelWidest'>{{:value.name}}:</div></td>
<td><div class='floatLeft tooltipRight' data-tooltip='{{:tooltiptext(value.req_text, value.catalyst_text, value.tool_text)}}'>
{{:helper.link('Craft', 'gears', {'make': value.ref})}}
</div></td>
</tr>
{{/for}}
{{if !data.display_craftable_only}}
{{for data.cant_craft}}
<tr>
<td><div class='itemLabelWidest'>{{:value.name}}:</div></td>
<td><div class='floatLeft tooltipRight' data-tooltip='{{:tooltiptext(value.req_text, value.catalyst_text, value.tool_text)}}'>
{{:helper.link('Craft', 'gears', {'make': value.ref}, 'disabled')}}
</div></td>
</tr>
{{/for}}
{{/if}}
</table>
</article>
</div>
{{else}}
{{for data.can_craft}}
<div class='display'>
<header><h3>{{:value.name}}</h3></header>
<article>
{{if value.req_text}}
<div class='item'>
<div class='itemLabel'>Requirements:</div>
<div class='itemContent'>{{:value.req_text}}</div>
</div>
{{/if}}
{{if value.catalyst_text}}
<div class='item'>
<div class='itemLabel'>Catalysts:</div>
<div class='itemContent'>{{:value.catalyst_text}}</div>
</div>
{{/if}}
{{if value.tool_text}}
<div class='item'>
<div class='itemLabel'>Tools:</div>
<div class='itemContent'>{{:value.tool_text}}</div>
</div>
{{/if}}
<div class='item'>
{{:helper.link('Craft', 'gears', {'make': value.ref})}}
</div>
</article>
</div>
{{/for}}
{{if !data.display_craftable_only}}
{{for data.cant_craft}}
<div class="display">
<header><h3>{{:value.name}}</h3></header>
<article>
{{if value.req_text}}
<div class='item'>
<div class='itemLabel'>Requirements:</div>
<div class='itemContent'>{{:value.req_text}}</div>
</div>
{{/if}}
{{if value.catalyst_text}}
<div class='item'>
<div class='itemLabel'>Catalysts:</div>
<div class='itemContent'>{{:value.catalyst_text}}</div>
</div>
{{/if}}
{{if value.tool_text}}
<div class='item'>
<div class='itemLabel'>Tools:</div>
<div class='itemContent'>{{:value.tool_text}}</div>
</div>
{{/if}}
</article>
</div>
{{/for}}
{{/if}}
{{/if}}
</article>
</div>
{{if data.busy}}
<div class="mask">
<div class="maskContent">
<h1>Crafting...</h1>
</div>
</div>
{{/if}}
+1
View File
@@ -1815,6 +1815,7 @@
#include "code\modules\nano\interaction\default.dm"
#include "code\modules\nano\interaction\inventory.dm"
#include "code\modules\nano\interaction\inventory_deep.dm"
#include "code\modules\nano\interaction\not_incapacitated.dm"
#include "code\modules\nano\interaction\physical.dm"
#include "code\modules\nano\interaction\self.dm"
#include "code\modules\nano\interaction\zlevel.dm"