http://www.bay12forums.com/smf/index.php?board=29.0
Also:
df.item_type[type] gives you the ID, you don't need that table lookup. df.item_type[id] gives you the type, as well.
This looks great! Is there anywhere with all your scripts, and have you considered adding them to standard DFHack?
Is there a chance for this to add/parse any additional information like description which is not visible to DF parser? It would be amazing to use this to actually explain what weapons/armors are and what they fit for.
That would be amazing, I always missed this possibility to describe what you add to total conversion mods so people would not be so confused.
Item descriptions... awesome!
This is a thing. This specific thing is a noun. It is composed of matter, and has both a size and an appearance.
I like that the descriptions file wouldn't interfere with anything if the script is not installed, but it might be better to have it tucked in a corner of the raw folder. That way it should copy with a save and pack nicely with a mod.
No sweat if that's not feasible, it's not like Stonesense puts its custom item data under raw either.
Wooo, thank you very much for including it straight away! I am making my new mod from the scratch, so it's easier to include everything as I go and add items (and I mean it, I think I'm making everything but base materials) than to go through everything later and add descriptions.That would be amazing, I always missed this possibility to describe what you add to total conversion mods so people would not be so confused.
Done, now there is a possibility to make descriptions for every item. I did not add any descriptions except some examles. Instructions also included in this release. I really hope people will be interested in this and fill descriptions for vanilla items (may just be short summaries from the wiki)
Wooo, thank you very much for including it straight away! I am making my new mod from the scratch, so it's easier to include everything as I go and add items (and I mean it, I think I'm making everything but base materials) than to go through everything later and add descriptions.
If you knew how many people wished for something like that. This is amazing. Truly. In terms of user-friendlyness, this trumps twbt's itemgraphics by far.
Custom descriptions of items. :o
Damn...
Hell yeah, DOOM Roguelike-style! Does it support colored characters?If you knew how many people wished for something like that. This is amazing. Truly. In terms of user-friendlyness, this trumps twbt's itemgraphics by far.
Custom descriptions of items. :o
Damn...
If you put some labor in the text file.. you can even have ASCII images of the items XD
Or this could be handy in-game wiki articles replacement, though it need a lot of time to fill everything...
Hell yeah, DOOM Roguelike-style! Does it support colored characters?
Yes, I was thinking of an ingame manual replacement. At least concerning items.
I do that already with my "===SKILL x===" reactions in workshops, to let players know which skill they need in workshops. But this? Its much better.
The less outside info I have to force-feed players (through third-party means, like a manual), the more accessable the mod will be.
You could also write more in-game help files with the WTF editor.
Thanks, going to bed now, I will make sure to test it tomorrow. I cannot explain how happy I am that this exists.Same here :)
Thanks, going to bed now, I will make sure to test it tomorrow. I cannot explain how happy I am that this exists.Same here :)
Its perfect for Peridexis beginner pack too. More player info is always nice.
You can put URLs in it, and if the player presses ENTER then DF will minimize and the link will open in the default browser. I tested that.That's in WTF text. Since I don't know how complicated it would be to render WTF on the item description screen, I was asking if it's possible to launch a URL from DFHack (from an alt-h command or something).
You can put URLs in it, and if the player presses ENTER then DF will minimize and the link will open in the default browser. I tested that.That's in WTF text. Since I don't know how complicated it would be to render WTF on the item description screen, I was asking if it's possible to launch a URL from DFHack (from an alt-h command or something).
Of course, if WTF is trivial then it's a moot point.
Edit: Link to the WTF editor (http://dffd.bay12games.com/file.php?id=4175). Still don't know what it takes to render WTF text to the screen.
The main problem is that Lua interacts with the text viewscreen really weirdly. AFAIK it's a char[], but it just treats it as a char or something so it displays wrongly.
I meant formatted_text, sorry.
:o
Omg, that will be such a fun project. Large ascii item and creature graphics for vanilla, I think I might do that. :D
Once you release this, please make sure to include an idiot-proof manual plus example for people to work with.
I think black and white ascii is perfectly fine.
Is the size affected by the tileset you use? Did you try this out with Twbt? It looks like you got a pretty high screen resolution, I'm just wondering what happens to people that play on a netbook/laptop.
Best to figure out which resolution works best with which size. I could imagine that a 1024 set and a set for 1920 would be reasonable. Same images, just compressed size for the people with smaller screens.
Do you have an extra tileset for this? Like a text-only tileset, or is your ascii image displayed in actual characters/glyphs/text?
The TWBT, Rendermax and Stonesense demonstrated that you can do something other than putting standard-color glyphs on the screen, though it does require delving into C++.
As with the Dwarf Visualizer, this is the kind of utility that could really, really use a way to blit a bitmapped image onto the DF screen. Or even a pop-up window from DFHack. Then there's no need to convert everything into ASCII, and scaling is much easier.
The Rube-Goldberg method would be to put a WTF link on the page that links to a local image file that would appear in the user's default browser.
Sorry if I wasn't clear, the idea was for a plugin jockey to suggest something about viewing images. An image capability that would really helpful to this project, but actually building it is obviously out of scope.The TWBT, Rendermax and Stonesense demonstrated that you can do something other than putting standard-color glyphs on the screen, though it does require delving into C++.
As with the Dwarf Visualizer, this is the kind of utility that could really, really use a way to blit a bitmapped image onto the DF screen. Or even a pop-up window from DFHack. Then there's no need to convert everything into ASCII, and scaling is much easier.
The Rube-Goldberg method would be to put a WTF link on the page that links to a local image file that would appear in the user's default browser.
I tried to find a way to paint a colored pixel image, but DFHack screen painting system is too complicated for me, have no idea how to make something actually appear on the screen :) ... Thats a task for DFHack devs, not me (at least at this moment).
Sorry if I wasn't clear, the idea was for a plugin jockey to suggest something about viewing images. An image capability that would really helpful to this project, but actually building it is obviously out of scope.
Depends what you mean by "paint".
https://github.com/DFHack/dfhack/blob/master/Lua%20API.rst#screen-api
There's a description of the "pen" object there.
EDIT: Also, your GetItemTypeID(item) can be replaced with item:getType() and df.item_type[item:getType()].
/Applications/Macnewbie_9.16/Macnewbie/Dwarf Fortress/data/save/region3-lowfps\raw\item_descriptions\WEAPON\ITEM_WEAPON_AXE_BATTLE.txt
Note the difference in slashes after data/save/ I suspect this issue is present on linux too.PTW, great work, also letting you know that 3.2 is in latest Macnewbie.
However: I copied the item_description folder to df/raw and to save/raw, but can't make descriptions appear in game.According to debug mode this is the path the script tries to access:Spoiler (click to show/hide)Code: [Select]/Applications/Macnewbie_9.16/Macnewbie/Dwarf Fortress/data/save/region3-lowfps\raw\item_descriptions\WEAPON\ITEM_WEAPON_AXE_BATTLE.txt
Note the difference in slashes after data/save/ I suspect this issue is present on linux too.
A different issue is with material properties illustrated here:Those long lines need to be formatted differently to be usable.Spoiler (click to show/hide)
1. Replaced the slashes in new version (which has been released just now)
2. I tested this with twbt and its standatd text tileset. I was to lazy to switch to 2D and check how it looks :) Ok its now just "fr." and" el.", hope this will be enough for strings to fit the screen.
Have you considered hosting this on Github (or another git host)? It would make tracking and merging changes a lot easier...Strongly agreed.
Also, this really should be in the utilities subforum.
@lethosor: Since the wiki already stores all the raws and the descriptions, do you think there's an easy way to generate a bunch of text files from that db with the descriptions and the proper file names to kickstart this project?There's no difference between what's stored on the wiki and the raw files (in fact, the raws on the wiki may be outdated).
For items that have descriptions in the raws, the wiki shows them in italics at the beginning of the article. fricy is asking for the equivalent text being extracted from the wikitext so that it can be made into a brief description for a vanilla item that doesn't have a DESCRIPTION tag.@lethosor: Since the wiki already stores all the raws and the descriptions, do you think there's an easy way to generate a bunch of text files from that db with the descriptions and the proper file names to kickstart this project?There's no difference between what's stored on the wiki and the raw files (in fact, the raws on the wiki may be outdated).
It would be easier to extract that text from the raws - it's only the value of the [DESCRIPTION] token for creatures. (What items are you referring to?)For items that have descriptions in the raws, the wiki shows them in italics at the beginning of the article. fricy is asking for the equivalent text being extracted from the wikitext so that it can be made into a brief description for a vanilla item that doesn't have a DESCRIPTION tag.@lethosor: Since the wiki already stores all the raws and the descriptions, do you think there's an easy way to generate a bunch of text files from that db with the descriptions and the proper file names to kickstart this project?There's no difference between what's stored on the wiki and the raw files (in fact, the raws on the wiki may be outdated).
Gems seem to do this fairly consistently; I'm not sure what else on the wiki is that predictable.
Pretty much every item in the game that can be "viewed" but doesn't have a description in the raws (weapons, armor, tools, toys, etc.) plus all of the materials. As I said, the gems might work, but I'm not too hopeful of finding a useable pattern in items' wikipages.It would be easier to extract that text from the raws - it's only the value of the [DESCRIPTION] token for creatures. (What items are you referring to?)For items that have descriptions in the raws, the wiki shows them in italics at the beginning of the article. fricy is asking for the equivalent text being extracted from the wikitext so that it can be made into a brief description for a vanilla item that doesn't have a DESCRIPTION tag.@lethosor: Since the wiki already stores all the raws and the descriptions, do you think there's an easy way to generate a bunch of text files from that db with the descriptions and the proper file names to kickstart this project?There's no difference between what's stored on the wiki and the raw files (in fact, the raws on the wiki may be outdated).
Gems seem to do this fairly consistently; I'm not sure what else on the wiki is that predictable.
ASCII pictures are still not displayed. Is there some configuration I'm missing to make them work?
Fracture/Yield are in Kilopascals, btw.
Hmm now that i look at this, you are using default viewscreen and just adding new strings to it. Maybe it would be better to have a new screen alltogether (and then e.g. canceling would quit from both screens). Though you would need to re-implement old behavior (reaction products?) but you could have more features (e.g. hyperlinks for item material/syndromes/castes/whatever, inline ascii art).
If you would like that i could try to make tutorial-ish viewscreen example.
table.insert(list,"Used to make soap"..dfhack.matinfo.decode(mat_type, mat_index).material.state_name.Liquid)
table.insert(list,"Used to make "..dfhack.matinfo.decode(mat_type, mat_index).material.state_name.Solid)
Yo I caught a dumbass little bug in how soap materials are reported.
So... oil has a sharpness? Ok.
Edit: (to say something constructive at least): Do you think it makes sense to post so many numbers? People that know what the molar mass, shear yield, impact yield, etc, mean are usually the same that can read raws.
But this should be a help for players, easy to understand. Maybe it could be more user-friendly, using descriptions/adjectives instead of numbers?
table.insert(list,"Temperature: "..item.temperature.whole.."U")
table.insert(list,"Temperature: "..item.temperature.whole.."U ("..math.floor((item.temperature.whole-10032)/1.8).." C)")
Ooh hey I have a suggestion now.
Replace this:Code: [Select]table.insert(list,"Temperature: "..item.temperature.whole.."U")
...with this:Code: [Select]table.insert(list,"Temperature: "..item.temperature.whole.."U ("..math.floor((item.temperature.whole-10032)/1.8).." C)")
(I can't make the °-sign appear right :()
So... oil has a sharpness? Ok.
Edit: (to say something constructive at least): Do you think it makes sense to post so many numbers? People that know what the molar mass, shear yield, impact yield, etc, mean are usually the same that can read raws.
But this should be a help for players, easy to understand. Maybe it could be more user-friendly, using descriptions/adjectives instead of numbers?
Can this be done for buildings too? I mean getting a description/more info?
Actually there is a really cool way to do that. And i'm still working on that (tweaking some stuff to get it right).Can this be done for buildings too? I mean getting a description/more info?
Within this script it can be done if you view an item that is part of the building's structure, and the script then checks the appropriate file. But simple pop-up script would be better.
Showing a little popup window with a picture of the buildings, name, skills used, and a short text description of what it does.
I think that's only possible with plugins, not scripts. You'd need to compile something in C for that, not just a .lua script.There is two ways. One is as Meph says - plugin written in c++ and compiled. That is the big idea i was talking about. Build one big plugin that does that centrally.
I think that's only possible with plugins, not scripts. You'd need to compile something in C for that, not just a .lua script.There is two ways. One is as Meph says - plugin written in c++ and compiled. That is the big idea i was talking about. Build one big plugin that does that centrally.
Other idea works only for workshops: you intercept the call to fill the sidebar and replace it with your own. That is how it works in the example i had before.
Did you replace the whole sidebar? Not just the choice list?Yup whole sidebar.
Yup whole sidebar.
Nope. Just some special jobs. But the idea is that you don't need to cover it fully and you could pass through interesting keypresses.QuoteYup whole sidebar.
So you have your jobs library finished and fully functional ? :) Can you properly issue any job using lua?
<FORMAT:NB_ASCII>
[32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32]
[32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32]
[32:32:32:32:32:214:196:194:196:196:194:196:196:196:196:196:196:196:196:196:196:196:196:196:219:219:179:32:32:32:32:32]
[32:32:32:32:32:211:196:196:196:196:196:196:196:196:196:196:196:196:196:196:196:196:196:196:219:219:179:32:32:32:32:32]
[32:32:32:32:32:32:32:0:0:0:0:32:32:32:32:32:32:32:32:32:32:32:32:32:178:178:179:32:32:32:32:32]
[32:32:32:32:32:32:32:0:32:0:0:32:32:32:32:32:32:32:32:32:32:32:32:47:176:176:179:32:32:32:32:32]
[32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:211:196:196:196:217:32:32:32:32:32]
[32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32]
[32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32]
obviously you've put a lot of work into this and its seems well received by the experienced players in the community;
however it is included in the LNP and is on by default. I couldn't work out how to turn it off.
I looked at a dwarfs thoughts and preferences and couldn't get out of the screen. all I saw was ascii art (over the text I wanted to read) and some text at top and bottom "dfhack" and "ascii view". no "esc = exit" which I saw in this thread and may be a more recent addition. when I googled "dfhack ascii view turn off" I wasn't able to find anything.
finally found this thread after half an hour.
I've just realised that I can use it to make in-game tutorials for custom workshops. You can simply make a "chemistry manual" item and add all reagents/reactions/descriptions to its description.
Well the material is going to be paper, that's for sure. I will just make different tool types, that's it. Can you please introduce some kind of a "parameter" system so we could omit material properties/temperature/sharpness selectively for specific items/materials. I.e. I want this information for weapons but don't want for musical instruments.
/home/thefunk/.df24/hack/scripts/nb_item_info.lua:486: Cannot read field vector<descriptor_color*>.-1: index out of bounds.
stack traceback:
[C]: in function '__index'
/home/thefunk/.df24/hack/scripts/nb_item_info.lua:486: in function 'GetMatPropertiesStringList'
/home/thefunk/.df24/hack/scripts/nb_item_info.lua:953: in function </home/thefunk/.df24/hack/scripts/nb_item_info.lua:841>
vector<descriptor_color*>.-1I haven't tried to track this down, but errors like these are typically caused by attempting to use df.some_enum.NONE (usually -1) as an array index.
I don't see the point of ASCII art when you can just include an image tbh.In that case I would include an image.
--Written by Putnam
local widgets=require('gui.widgets')
local gui=require('gui')
local dlg=require('gui.dialogs')
local GraphicalButton=defclass(GraphicalButton,widgets.Widget)
GraphicalButton.ATTRS={
on_click = DEFAULT_NIL,
on_rclick = DEFAULT_NIL,
graphic = DEFAULT_NIL, --refers to the name of a tilepage
label = DEFAULT_NIL
}
function GraphicalButton:preUpdateLayout()
self.frame=self.frame or {}
if not self.page then self.frame.w=0 self.frame.h=0 return end
self.frame.w=self.page.page_dim_x
self.frame.h=self.page.page_dim_y
end
function GraphicalButton:onRenderBody(dc)
if not self.page then return end
for k,v in ipairs(self.page.texpos) do
dc:seek(k%self.frame.w,math.floor(k/self.frame.w)):tile(32,v)
end
end
function GraphicalButton:onInput(keys)
if keys._MOUSE_L_DOWN and self:getMousePos() and self.on_click then
self.on_click()
end
if keys._MOUSE_R_DOWN and self:getMousePos() and self.on_rclick then
self.on_rclick()
end
end
function GraphicalButton:init(args)
if not self.graphic then return end
for k,v in ipairs(df.global.texture.page) do
if v.token==self.graphic then self.page=v return end
end
error('No tilepage found: '..self.graphic)
end
local GraphicsBox=defclass(GraphicsBox,dlg.MessageBox)
GraphicsBox.ATTRS{
frame_style = gui.GREY_LINE_FRAME,
frame_inset = 1,
-- new attrs
on_accept = DEFAULT_NIL,
on_cancel = DEFAULT_NIL,
on_close = DEFAULT_NIL,
}
function GraphicsBox:onRender()
self.super.onRender(self)
self:renderSubviews()
end
function GraphicsBox:getWantedFrameSize()
local button=self.subviews.image
if not button.frame then return end
return button.frame.w,button.frame.h
end
function GraphicsBox:init(info)
self:addviews{
GraphicalButton{
view_id = 'image',
graphic = info.graphic,
frame = {l=0,t=0}
}
}
end
function showImage(title,image,on_close)
GraphicsBox{
frame_title=title,
graphic=image,
on_close=on_close
}:show()
end
local lastFrame=df.global.enabler.frame_last
dfhack.onStateChange.itemPictures=function(code)
if code==SC_VIEWSCREEN_CHANGED and dfhack.isWorldLoaded() then
if dfhack.gui.getCurViewscreen()._type==df.viewscreen_textviewerst and df.global.enabler.frame_last-lastFrame>df.global.enabler.gfps*20 then
lastFrame=df.global.enabler.frame_last
local parent=dfhack.gui.getCurViewscreen().parent
if parent._type==df.viewscreen_unitst or parent._type==df.viewscreen_dungeon_monsterstatusst then
local unit=parent.unit
local imageExists=false
local creature=df.creature_raw.find(unit)
for k,v in ipairs(df.global.texture.page) do
if v.token==creature.creature_id..'_TEXT_IMAGE' then
imageExists=true
break
end
end
if imageExists then
showImage("Image",creature.creature_id..'_TEXT_IMAGE')
end
elseif parent._type==df.viewscreen_itemst then
local item=parent.item
local imageExists=false
local itemName=''
local subtype=dfhack.items.getSubtypeDef(item:getType(),item:getSubtype())
if subtype then
itemName=df.item_type[item:getType()]..'/'..subtype.id --gotta be a slash methinks
else
itemName=df.item_type[item:getType()]
end
for k,v in ipairs(df.global.texture.page) do
if v.token==itemName..'_TEXT_IMAGE' then
imageExists=true
break
end
end
if imageExists then
showImage("Image",itemName..'_TEXT_IMAGE')
end
end
end
end
end
graphics_putnam_godtier
[OBJECT:GRAPHICS]
[TILE_PAGE:PUTNAM_GODTIER]
[FILE:putnam/godtier.png]
[TILE_DIM:64:64]
[PAGE_DIM:12:1]
[TILE_PAGE:CHAIR_TEXT_IMAGE]
[FILE:putnam/spender.PNG]
[TILE_DIM:16:16]
[PAGE_DIM:7:12]
[CREATURE_GRAPHICS:GRAPHICS_CREATURE_FORTBENT]
[DEFAULT:PUTNAM_GODTIER:0:0:ADD_COLOR:DEFAULT]
[MINER:CHAIR_TEXT_IMAGE:0:0:ADD_COLOR:DEFAULT]
[CREATURE:GRAPHICS_CREATURE_FORTBENT]
[ARENA_RESTRICTED]
[NAME:none:none:none]
[DESCRIPTION:none:none:none]
[CASTE_NAME:none:none:none]
[DOES_NOT_EXIST]
[TILE_PAGE:CHAIR_TEXT_IMAGE]
[FILE:putnam/spender.PNG]
[TILE_DIM:16:16]
[PAGE_DIM:7:12]
Oh, crap, forgot the most important part. GRAPHICS must be set to YES, even if the user is using ASCII. This could cause a real problem, now that I think of it.I figured that after your sentece
As long as a creature--ANY creature--loads a tileset, it can be used in graphics this way.What happens if someone turns GRAPHICS to NO? Super-crash-party, or simply nothing?
--Written by Putnam
local widgets=require('gui.widgets')
local gui=require('gui')
local dlg=require('gui.dialogs')
local GraphicalButton=defclass(GraphicalButton,widgets.Widget)
GraphicalButton.ATTRS={
on_click = DEFAULT_NIL,
on_rclick = DEFAULT_NIL,
graphic = DEFAULT_NIL, --refers to the name of a tilepage
label = DEFAULT_NIL
}
function GraphicalButton:preUpdateLayout()
self.frame=self.frame or {}
if not self.page then self.frame.w=0 self.frame.h=0 return end
self.frame.w=self.page.page_dim_x
self.frame.h=self.page.page_dim_y
end
function GraphicalButton:onRenderBody(dc)
if not self.page then return end
for k,v in ipairs(self.page.texpos) do
dc:seek(k%self.frame.w,math.floor(k/self.frame.w)):tile(32,v)
end
end
function GraphicalButton:onInput(keys)
if keys._MOUSE_L_DOWN and self:getMousePos() and self.on_click then
self.on_click()
end
if keys._MOUSE_R_DOWN and self:getMousePos() and self.on_rclick then
self.on_rclick()
end
end
function GraphicalButton:init(args)
if not self.graphic then return end
for k,v in ipairs(df.global.texture.page) do
if v.token==self.graphic then self.page=v return end
end
error('No tilepage found: '..self.graphic)
end
local GraphicsBox=defclass(GraphicsBox,dlg.MessageBox)
GraphicsBox.ATTRS{
frame_style = gui.GREY_LINE_FRAME,
frame_inset = 1,
-- new attrs
on_accept = DEFAULT_NIL,
on_cancel = DEFAULT_NIL,
on_close = DEFAULT_NIL,
}
function GraphicsBox:onRender()
self.super.onRender(self)
self:renderSubviews()
end
function GraphicsBox:getWantedFrameSize()
local button=self.subviews.image
if not button.frame then return end
return button.frame.w,button.frame.h
end
function GraphicsBox:init(info)
self:addviews{
GraphicalButton{
view_id = 'image',
graphic = info.graphic,
frame = {l=0,t=0}
}
}
end
function showImage(title,image,on_close)
GraphicsBox{
frame_title=title,
graphic=image,
on_close=on_close
}:show()
end
local lastFrame=df.global.enabler.frame_last
dfhack.onStateChange.itemPictures=function(code)
if code==SC_VIEWSCREEN_CHANGED and dfhack.isWorldLoaded() then
if dfhack.gui.getCurViewscreen()._type==df.viewscreen_textviewerst and df.global.enabler.frame_last-lastFrame>df.global.enabler.gfps*20 then
lastFrame=df.global.enabler.frame_last
local parent=dfhack.gui.getCurViewscreen().parent
if parent._type==df.viewscreen_unitst or parent._type==df.viewscreen_dungeon_monsterstatusst then
local unit=parent.unit
local imageExists=false
local creature=df.creature_raw.find(unit)
for k,v in ipairs(df.global.texture.page) do
if v.token==creature.creature_id..'_TEXT_IMAGE' and v.loaded then
imageExists=true
break
end
end
if imageExists then
showImage("Image",creature.creature_id..'_TEXT_IMAGE')
end
elseif parent._type==df.viewscreen_itemst then
local item=parent.item
local imageExists=false
local itemName=''
local subtype=dfhack.items.getSubtypeDef(item:getType(),item:getSubtype())
if subtype then
itemName=df.item_type[item:getType()]..'/'..subtype.id --gotta be a slash methinks
else
itemName=df.item_type[item:getType()]
end
for k,v in ipairs(df.global.texture.page) do
if v.token==itemName..'_TEXT_IMAGE' and v.loaded then
imageExists=true
break
end
end
if imageExists then
showImage("Image",itemName..'_TEXT_IMAGE')
end
end
end
end
end