Giter Site home page Giter Site logo

buildingeditor's People

Contributors

vache avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

ufft47

buildingeditor's Issues

Editing Specials

To resize a special, use the new layout to iterate the existing model, set new items as active, and removed items as inactive. Will have to recalculate the new sizes and everything to resize the display.

Overmap Specials

Have to use wizard to make a special. On the overmap special page of the wizard, have a vertical slider with 21 levels (z+10, 0, z-10) and a 10x10 (or 9x9?) grid. Toggling a cell in the grid enables that 24x24 area for the current slider level in the editor. Disabled grid areas are greyed out. This seems like best way to support irregular shapes. Possibly include preset sizes for easy selection of common shapes: 2x2, 3x3, 5x5, etc?

As mentioned in #9, the overmap terrain data can keep track of up/down, we can also keep track of the tripoint location of the terrain with the GOES_UP/GOES_DOWN flag and use these locations to mark squares on the map drawer to help line things up. Exporting could automatically check the OMTs to make sure the ups and downs line up, and display a warning if not (but still allow the export, it could be desired behavior).

One problem, how do we line things up if the specials aren't really aligned? Say z=0 is 3x3 starting at 1,1 and z=1 is 5x5 starting at 0,0. When we're on z=0, we want the top left to be 1,1,0, and on z=1, we want top left to be 0,0,1. Ideally it should recalculate when the z level changes.

  • May not actually want to do it this way, it could be disorienting. Will have to test different methods before deciding, or could add it as a configuration option.

The fill terrain should be the open_air terrain, or some other "open below" terrain. On higher z levels, maybe replace the draw character of "open below" terrain to the character of the z-below, perhaps with a different background color to signify that it is below. It should probably even be that positive z levels should be filled with open air, and negative z levels should be filled with rock. This will accomplish a few goals, filling the area with a good default terrain, and helping the user line up terrain like walls and stairs. Negative z levels will require some other way to align stairs, maybe placing GOES_UP / GOES_DOWN terrain automatically places its pair on the opposite level? Problem is, the relationship between up/down variants is not preserved in json.

Mapgen Specials

Specials to be Accounted For:
(See https://github.com/CleverRaven/Cataclysm-DDA/blob/master/data/json/mapgen/mapgen-test.json and https://github.com/CleverRaven/Cataclysm-DDA/blob/master/doc/MAPGEN.md)

  • Vending Machines - "place_vendingmachines": [ { "x": 3, "y": 1, "item_group": "jewelry_front" } ],
  • Toilets - "place_toilets": [ { "x": 9, "y": 1, "amount": [ 88, 111 ] } ], Note: need to add "amount" support to current.
  • Signage - "place_signs": [ { "x": 7, "y": 1, "signage": "it works again." } ],
  • NPCs - "place_npcs": [ { "class": "bandit", "x": 15, "y": 13 } ] Note: "class" comes from data/json/npcs/npc.json, the "id" field.
  • Radiation - "set":[ { "point":"radiation", x: [1, 3], y: 2, "amount": [3, 16] } , { "square":"radiation", "amount":50, "x":1, "y":1, "x2":8, "y2":8 }, { "line":"radiation", "amount":30, "x":1, "y":1, "x2":10, "y2":10 } ] Note: need to combine into squares. Can be done same way as rest of the groups probably.
  • Field - "fields": { "B": { "field": "fd_blood", "age": 10, "density": 1 } } or "place_fields": [ { "x": 5, "y": 1, "field": "fd_bile", "age": 20, "density": 2 } ],
  • Gas Pump - "place_gaspumps": [ { "x": 1, "y": 1, "amount": [ 200, 222 ] } ], Note: place_gaspump randomly selects diesel or gas. The json should probably be modified to allow the user to pick one or the other, and only randomly assign when one is not specified.
  • Vehicle - "place_vehicles": [ { "x": 5, "y": 3, "vehicle": "unicycle", "chance": 100, "status": 1 } ],
  • Vehicle Groups - Same as above but with group ID instead of vehicle ID.
  • Make Rubble - "place_rubble": [ { "x": 10, "y": 1 } ], optionally: "place_rubble": [ { "x": 10, "y": 1, "rubble_type":furniture_id, "items":false, "floor_type":terrain_id, "overwrite":true } ]

Building Models

During wizard ask if user is creating a special. If not, continue with model being the size of one OMT. Else continue to the special page.

Maximum size of a special is 10x10 (maybe 9x9?). Represent the selected portions with a 2D array of bools, toggle to true if user selects that cell during the special creation.

If special, then main model consists of a map<tripoint, OMT>, otherwise, main model consists of a single OMT. The view area is (max(x) * 24, max(y) * 24), and this area is recalculated depending on z level. The clicked OMT is (clickx / 24, clicky / 24, z-level slider value), and the selected tile within that is (clickx % 24, clicky % 24). If the clicked tile is in an inactive OMT (a grid that is marked as false in the 10x10 array), nothing happens. These OMTs will be grayed out in the view.

While building specials, may be worthwhile to have the user able to isolate a single OMT from the special.

OMT Metadata

Special object that is a member of OMT's created to hold OMT metadata for export, like id, name, rotate, etc.

Most of it will come directly from the wizard, but some fields can be derived by existence of certain terrains, like "GOES_UP", "GOES_DOWN" for known_up, known_down. These should be calculated automatically whenever a terrain with this type gets placed, to assist with lining up z-level connections for specials.

TODO

  • Rotate setting needs to propagate through from special settings to individual OMT
  • If special is marked as rotate, the OMT IDs should have _north appended on them
  • Empty OMT datas should not be exported
  • Exported OMT datas should have correct ID
  • Tile editor
  • JSON writing should reuse directories
  • JSON object writing, objects should have a ToJson method like the data objects
  • JSON writer code should be more cohesive in general
  • JSON output should be as close to current format as possible
  • Correct some design elements, like passing data around from the wizard
  • Create "Edit" windows to edit omt and special data
  • Fix up menus
  • Linux build
  • Occurrences and max city distance not working correctly
  • Special connections, and ui for them
  • Drawing up/down connections and walls
  • Undo stack
  • Rotate/flip
  • Layers
  • Draw vehicle size
  • Check for invalid tiles on export
  • Split items into collapsible categories
  • Crash when clicking "select" at search results without a search result clicked
  • Crash when move slider to z-10 in main view
  • Tile support... one day...

Wizard

Run on first load, or when selecting "new->using wizard".

Wizard pages:

  • Editor Settings: Set data directory, toggle grid, etc. (maybe move this to a button under building settings?) Z-levels enabled? Which mods are we allowed to include? Is this structure a part of a mod, if so, which mod?
  • Overmap Settings: Part of a new overmap special, new overmap terrain, or existing overmap terrain? If new special, go to special settings, if new omt, go to omt settings, if existing, select overmap terrain, input weight and comment. If existing omt, also display current variants and their weights? Only works for json mapgens, but could help user determine a reasonable weight.
  • Special Settings: overmap_specials.json options: id, locations, city distances, occurrences, flags, rotate, and unused fields (required, unique, city sizes)? Shape selector as mentioned in #2, also include road connections on this page as well.
  • Terrain Settings: If a special, have an option to "copy previous" to apply all settings from the last specified terrain. Otherwise, have all of the overmap_terrain.json options: id, name, rotate, symbol, color, see cost, extras, known down, known up, monster density, dynamic spawns, sidewalk, allow_road (allows road to overwrite the terrain during generation)

Overmap specials have the potential to make this very large. If we assume a fully filled 10x10x21 special, we would have 2100 terrain settings pages, and 21 shape selections in the special settings. This could be simplified a bit. Interior and underground OMTs could be assumed to have max see cost; under and above ground to have no sidewalk or allow road; known_up/known_down can be determined through terrain placed in each instead of user input. We could also allow these settings to be "painted". There could be an extra page for specials with tools that allow the user to set the terrain values, then let them click and draw on a table representing the special and it applies those settings to those OMTs. This could even be integrated with the process of selecting which tiles are going to be active.

GUI for Editing Values

When user places a nondrawable or special, these fields usually require some sort of user input for values like a chance, amount, density, etc. There needs to be a way to set and edit these fields easily without getting in the user's way and without complicating the GUI needlessly. Ideally, there should be ONE class/GUI that adapts to the input given to it.

One idea is a toolbar that appears at the top and will display whatever items that can currently be edited, like the font toolbar in word/writer.

Could also include a small pop up window that appears when clicking on a cell with values that can be edited, when in a "select" or "edit values" mode. However, this doesn't really support "on-the-go" editing. This way would be easier to handle "list" fields, like individual items in a cell.

Likely solution will involve both of the above, with the second method being more of a "tile detail" window that lets the user see everything in a current cell with options to edit the values.

Erasing Features

New erase button has been added. Remove the various clear/erase options for individual features. Might want to look into having the feature set when swapping tabs, so that users don't have to swap tabs, then select a thing from the box to erase that feature.

Mod Support

When parsing a json in a /mod/*/ directory, place identified items in a map<mod_name, item_id>. In options/wizard menu, list the mods detected, give user the option to enable/disable showing items from mods. Denote modded items in the item lists with an * and include the mod name in the tooltip.

Release 2 Checklist

  • Tooltips where appropriate.
  • Finalize OMT data and dialog.
  • "Select" tool, and way to edit existing tile data.
  • Fix the menus, add a help window, and maybe add an about page
  • Revisit placement rule enforcement

JSON Loading

Might be worth it to track some files with "type":"overmap_terrain", and "om_terrain":[ "omt" ], so that it is easier to look up things like overmap_special->overmap_terrain->mapgen.

Something like Map<omt id, filename> to help track down mapgens.

Release Checklist

Release for single omt sized editor:

  • Group... grouping. Make contiguous instances of groups into a single rectangle for json output. Use system similar to old design, make list of groups and a map of groupname->array of indices where the group exists, then step through the arrays and make a combined rectangle of the area.
  • Toilets. Pretty basic.
  • Basic instruction guide.
  • Make the data path not hardcoded - use QFileDialog to get the filename as soon as software starts. Possibly use QSettings to keep track of last path selected.
  • Tooltips where relevant - modded items should have the mod in the tooltip, all of the buttons and options in the object editors.
  • Prompt on write for overmap terrain & weight, until better system is ready - use QInputDialog to grab these values on write without having to write something more robust.
  • Clear tiles option for furniture/vehicles/items/etc.
  • Feedback for setting the nondrawable items - message in statusbar or some sort of highlight.
  • Export the traps.
  • Make export "Write" file dialog automatically try to force .json filename, also, select the user inputted "data" (or data/json/mapgen) directory as the target location.
  • Figure out how to deploy correctly in stupid qt.

Optional:

  • Status bar updates when things change.
  • Reset option - set the whole model back to blank everything.
  • Work out line drawing for walls.
  • Possibly check and enforce placement rules (NOITEM tags on furn/terrain, use movecost=0 on terrain or movecostmod=-1 on furn to prevent monster placement)
  • Light up tiles that are selected with rubberband tool - set indices in rubberband area as selected for blue highlight.
  • Prettify the json, use multiple documents to set some fields as compact, and to get the layout of the generated jsons close to the handmade jsons.
  • Search box for features. Pain in the ass trying to find a specific entry in the list sometimes.

Exporting JSON

If writing to a single QJsonDocument, exported document comes out in alphabetical order, making the final product look out of order. Look into using multiple QJsonDocuments, then combining their outputs into a single file at the end.

Improving Indexing

Tripoint indexing to map is slow for the # of times the data() function in the model needs to be called. Map should be converted to list, with function for converting (x, y, z) to listindex. Ideally, would like to maintain z as supporting min and max of -10 to 10.

OMTs are always 24x24, so they will still be represented as 2d array. Easiest way would be to start at (0, 0, 10) and work down to (23, 23, -10).

QModelIndex to x, y, z index:

omt_row = index.row / omtwidth
omt_col = index.col / omtwidth
omt_z = z

x, y, z index to list index:
2d: omt_index = (y * MAX_Y) + x
3d: omt_index = ((MAX_Z - z) * MAX_Y * MAX_X) + (y * MAX_Y) + x
MAX_Z & MAX_Y & MAX_X are the highest z level occupied, highest y coordinate of omt, and highest x coordinate of omt. They can all be calculated when the model is created.

OMT Index in list from QModelIndex: (max of 10x10x21)
omt_index = ((MAX_Z - z) * MAX_Y * MAX_X) + ((index.row / omtwidth) * MAX_Y) + (index.col / omtwidth)

The tile index within the OMT will remain unaffected.

The Z level slider will send value to the model, model will save value and use it in the data() method to determine which index to grab.

Exporting the JSON

Get OMTs from the model, skip the inactive ones. Have a list of available characters (a-z, A-Z, 0-9, and the symbols), then for each OMT, find the combinations of ter/furn/trap with the most occurrences, take their list of desired characters, and check the available character list, if the most desired character is available, remove it from the list and assign it to that combo.

Desired characters are selected by the tiles display character first (the furniture/trap symbol if one of those exists, or the terrain symbol if not), then the first letter of the name of the furniture/trap or the terrain. The | and - characters will be reserved for the most common terrains with the flag WALL or AUTO_WALL_SYMBOL. Similarly, reserve characters like _ , . ` for terrains with the FLAT tag.

If writing to a single QJsonDocument, exported document comes out in alphabetical order, making the final product look out of order. Look into using multiple QJsonDocuments, then combining their outputs into a single file at the end.

Nice to Haves

Item group and monster group explorer to let the user get an idea of what has a chance to spawn within a given item group. Would be easy to calculate total weights and and % of a chance for a given item to spawn. Difficulty lies mostly in keeping track of the info, making a GUI to show it, and getting to that GUI while also keeping it simple and easy to use.

If computer JSON ever gets in, how would they be added to maps? Could be possible to pop up a computer add GUI when the terminal terrain is placed, or have some sort of export wizard at the end to add computers in before it is saved as json. How would it load the computers in? Currently all other items are dynamically loaded through json, and even if computers became jsonified, the actions would still be hardcoded (until the future when possibly they're not). Might be okay to create a computers.json that computer action creators need to manually update when adding a computer action as part of the main cata repo, OR as part of the building editor that requires users to update it when it changes. Either way should prevent having the actions hard coded, but the first option is preferable.

Fields are currently not JSONed, but might be worthwhile to include, since fields would include things like the toxic gas spewers. Edit: fields can be placed in json but there is still not a json-ified definition of them anywhere.

Built in terrain/furniture creators to aid in development? Even possible to add item groups or monster groups. New monsters and items might be pushing major scope creep though, but something to consider.

Automatically adding newly created items to their appropriate files? New specials into overmap_specials.json, new overmap terrains in overmap_terrain.json, etc.

Simulator dialog that will attempt to create the structure using the groups and settings specified the same way the game would use them to give users an idea of what and how many items would spawn, etc. Alternately, do a rough estimation of number and type of enemies, items, etc. and display it to user right before write.

Flags and Valid Placement Calculations

https://github.com/CleverRaven/Cataclysm-DDA/blob/master/doc/JSON_FLAGS.md

Terrain, Furniture, & Traps

  • Terrain: move_cost == 0 should prevent placement of furniture or traps. The flag FLAT may be enough for most things, but this is not exhaustive.
  • Any furniture should prevent trap placement and vice versa.

Items:

  • Terrain/Furniture: flags NOITEM DESTROY_ITEM prevent item placement. Note: this means things like vending machines and gas pumps will be forced to use the specials for placement.

Monsters & NPCs:

  • Terrain: move_cost == 0 should prevent placement
  • Furniture: move_cost_mod == -1 should prevent placement
  • Traps: benign == true traps only

Vehicles:

  • Only allow placement on FLAT or ROAD terrain with no furniture? Or TINY or NOCOLLIDE furniture/terrain?

Fields:

  • No restrictions

Other flags we need to know:

  • AUTO_WALL_SYMBOL for drawing walls correctly
  • GOES_DOWN and GOES_UP for specials.

Next Goals

  1. Enforce placement rules. Add rules to rest of the specials.
  2. Create overmap_terrain json as well as mapgen json. This will need to include a UI for entering all the data (manually for now, we can calculate some fields in the future based on the map design). Need to work out a good omtdata to omtmodel connection for specials. May need to work the wizard in to this part to be able to track the association closely enough.
  3. Add support for the rest of the special mapgen features, notably NPCs, fields, vending, and gas pumps.
  4. Clean up code, clear out as many TODOs as it makes sense to, add static "null" types, etc. with focus mostly on improving code quality since the majority of drawing features should be in.
  5. Clean up the UI a bit, add tooltips, colors, helpful info wherever possible. Maybe work on showing multiple feature colors on one tile.
  6. Add "Open" option to load an existing single omt sized mapgen json for modification. Loads terrain/furniture only right now. Needs to load everything else.
  7. Optimize for specials, specifically look into the indexing system to improve OMT and tile lookup in the model, because the data() method gets hit several times for each tile any time the UI changes, including move/resize, and moderate slowdowns are noticeable even at one OMT sized area. Also look into using pointers for the tiles and OMTs to speed things up there.
  8. Simple 1 z-level special support, including UI for layout, and other fields.
  9. Polish. Line up walls, get fonts sorted, highlight cells that will be written, display feedback to status bar, add select tool, possibly circle drawing tools.
  10. Extend "Open" functionality to specials.
  11. Add z-level functionality.

Tile Editor

Use a tree view on top of the regular model, tree expands to different features of each tile and each property of those features.

Representing Nondrawable Items

MonsterGroups & ItemGroups:
The widget list just needs IDs, which can just be typedef-ed QStrings.
Tiles need the ID and a chance.
OMTs need the ID, chance, and a rectangle representing the area.
View: Red background for monster group, yellow background for item group?

User selects a group, then clicks a tile to place it. Something should appear contextually for the user to input the chance for the group. It should start with a sane default value and keep whatever value was input until changed. Should this be a part of the toolbar so that it is out of the way, but still available to the user? Think the font settings in word. What is easiest way to do this, have it support all of the types that need user intervention, and have it be unobtrusive and easily editable?

For the "nice-to-haves" we should parse the groups for their contents and weights, to allow the user to calculate chances of items spawning.

Monster:
Widget List: ID
Tile: ID, bool friendly (optional), QString name (optional)
OMT: pulls straight from Tiles
View: same background as monster group?

Item:
Widget List: ID
Tile: Array of Item IDs, int chance (one in chance of spawning)
OMT: pulls straight from Tiles
View: same background as item group?

Model View -> OMT/Tile Coordinates

Currently coordinates are determined by the model index then converted to OMT/Tile coordinates where needed, but this fails if the top left is not 0,0,z, as we would want it to be if the top row or left column is not 0. Once we have overmap specials implemented, there should be some way to determine an OMT index and we can use that in coordinate calculations to make sure we grab the right OMT.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.