void View::update(const InputState &state) { if(state.isKeyDown('g')) { if(m_is_visible) { if(m_cell_size == 3) m_cell_size = 6; else if(m_cell_size == 6) m_cell_size = 9; else { m_cell_size = 1; m_is_visible = false; } } else { m_cell_size = 3; m_is_visible = true; } } int height_change = state.mouseWheelMove() + (state.isKeyDownAuto(InputKey::pagedown)? -1 : 0) + (state.isKeyDownAuto(InputKey::pageup)? 1 : 0); if(height_change) m_height = clamp(m_height + height_change, 0, (int)Grid::max_height); { int actions[TileGroup::Group::side_count] = { InputKey::kp_1, InputKey::kp_2, InputKey::kp_3, InputKey::kp_6, InputKey::kp_9, InputKey::kp_8, InputKey::kp_7, InputKey::kp_4 }; for(int n = 0; n < arraySize(actions); n++) if(state.isKeyDownAuto(actions[n])) m_view_pos += worldToScreen(TileGroup::Group::s_side_offsets[n] * m_cell_size); } if((state.isKeyPressed(InputKey::lctrl) && state.isMouseButtonPressed(InputButton::left)) || state.isMouseButtonPressed(InputButton::middle)) m_view_pos -= state.mouseMove(); IRect rect = worldToScreen(IBox(int3(0, 0, 0), asXZY(m_tile_map.dimensions(), 256))); m_view_pos = clamp(m_view_pos, rect.min, rect.max - m_view_size); }
const IBox View::computeCursor(const int2 &start, const int2 &end, const int3 &bbox, int height, int offset) const { float2 height_off = worldToScreen(float3(0, height, 0)); int3 gbox(cellSize(), 1, cellSize()); int3 start_pos = asXZ((int2)( screenToWorld(float2(start + pos()) - height_off) + float2(0.5f, 0.5f))); int3 end_pos = asXZ((int2)( screenToWorld(float2(end + pos()) - height_off) + float2(0.5f, 0.5f))); start_pos.y = end_pos.y = height + offset; { int apos1 = start_pos.x % gbox.x; int apos2 = apos1 - gbox.x + bbox.x; start_pos.x -= apos1 < gbox.x - apos1 || bbox.x >= gbox.x? apos1 : apos2; } { int apos1 = start_pos.z % gbox.z; int apos2 = apos1 - gbox.z + bbox.z; start_pos.z -= apos1 < gbox.z - apos1 || bbox.z >= gbox.z? apos1 : apos2; } if(end == start) end_pos = start_pos; int3 dir(end_pos.x >= start_pos.x? 1 : -1, 1, end_pos.z >= start_pos.z? 1 : -1); int3 size(::abs(end_pos.x - start_pos.x), 1, ::abs(end_pos.z - start_pos.z)); size += bbox - int3(1, 1, 1); size.x -= size.x % bbox.x; size.z -= size.z % bbox.z; size = max(bbox, size); if(dir.x < 0) start_pos.x += bbox.x; if(dir.z < 0) start_pos.z += bbox.z; end_pos = start_pos + dir * size; if(start_pos.x > end_pos.x) swap(start_pos.x, end_pos.x); if(start_pos.z > end_pos.z) swap(start_pos.z, end_pos.z); int2 dims = m_tile_map.dimensions(); start_pos = asXZY(clamp(start_pos.xz(), int2(0, 0), dims), start_pos.y); end_pos = asXZY(clamp( end_pos.xz(), int2(0, 0), dims), end_pos.y); return IBox(start_pos, end_pos); }
void EntitiesEditor::drawBoxHelpers(Renderer2D &out, const IBox &box) const { int3 pos = box.min, bbox = box.max - box.min; int3 tsize = asXZY(m_tile_map.dimensions(), 32); drawLine(out, int3(0, pos.y, pos.z), int3(tsize.x, pos.y, pos.z), Color(0, 255, 0, 127)); drawLine(out, int3(0, pos.y, pos.z + bbox.z), int3(tsize.x, pos.y, pos.z + bbox.z), Color(0, 255, 0, 127)); drawLine(out, int3(pos.x, pos.y, 0), int3(pos.x, pos.y, tsize.z), Color(0, 255, 0, 127)); drawLine(out, int3(pos.x + bbox.x, pos.y, 0), int3(pos.x + bbox.x, pos.y, tsize.z), Color(0, 255, 0, 127)); int3 tpos(pos.x, 0, pos.z); drawBBox(out, IBox(tpos, tpos + int3(bbox.x, pos.y, bbox.z)), Color(0, 0, 255, 127)); drawLine(out, int3(0, 0, pos.z), int3(tsize.x, 0, pos.z), Color(0, 0, 255, 127)); drawLine(out, int3(0, 0, pos.z + bbox.z), int3(tsize.x, 0, pos.z + bbox.z), Color(0, 0, 255, 127)); drawLine(out, int3(pos.x, 0, 0), int3(pos.x, 0, tsize.z), Color(0, 0, 255, 127)); drawLine(out, int3(pos.x + bbox.x, 0, 0), int3(pos.x + bbox.x, 0, tsize.z), Color(0, 0, 255, 127)); }
void GroupEditor::drawContents(Renderer2D &out) const { int2 offset = innerOffset(); for(int n = 0; n < m_tile_group->entryCount(); n++) m_tile_group->entryTile(n)->m_temp = n; IRect clip_rect(int2(0, 0), clippedRect().size()); for(int n = 0; n < (int)m_tile_list.size(); n++) { const ui::TileList::Entry &entry = m_tile_list[n]; entry.is_selected = m_mode == mAddRemove? m_tile_group->isValidEntryId(entry.tile->m_temp, entry.tile) : entry.group_id == m_selected_group_id; IRect tile_rect = entry.tile->rect(); int2 pos = entry.pos - tile_rect.min - offset; if(areOverlapping(clip_rect, tile_rect + pos)) entry.tile->draw(out, pos); } DTexture::unbind(); for(int n = 0; n < (int)m_tile_list.size(); n++) { const ui::TileList::Entry &entry = m_tile_list[n]; if(!entry.is_selected) continue; Color col = m_tile_group->isEntryDirty(entry.tile->m_temp)? ColorId::red : ColorId::white; int2 pos = entry.pos - offset; out.addRect(IRect(pos, pos + entry.size), col); } if(m_mode == mModify && m_selected_group_id != -1) { IRect edit_rect(clippedRect().max - int2(280, 250), clippedRect().max - int2(5, 0)); int2 center = edit_rect.center(); out.setViewPos(-center); int2 half_size = edit_rect.size() / 2; out.addFilledRect(IRect(-half_size, half_size), FColor(0.3f, 0.3f, 0.3f)); drawBBox(out, IBox({-9, 0, -9}, {9, 1, 9}), ColorId::white); auto font = res::getFont(WindowStyle::fonts[0]); for(int n = 0; n < TileGroup::Group::side_count; n++) { out.setViewPos(-center - worldToScreen(TileGroup::Group::s_side_offsets[n] * 9)); font->draw(out, float2(0, 0), {ColorId::white}, format("%d", m_tile_group->groupSurface(m_selected_group_id, n))); } out.setViewPos(-center +edit_rect.size() / 2); font->draw(out, float2(0, 0), {ColorId::white}, format("setting surface: %d", m_selected_surface_id)); /* const char *names[] = { "", "snow", "gravel", "dirt", "grass", "mud", "mud_cracked", "sand", "green goo", }; out.setViewPos(-int2(bottom_rect.max.x - 200, bottom_rect.min.y)); for(int n = 0; n < arraySize(names); n++) font->draw(int2(0, 10), ColorId::white, m_selected_surface_id == n? "%d: [%s]\n" : "%d: %s\n", n, names[n]); */ out.setViewPos(-clippedRect().min); } if(m_current_entry) m_font->draw(out, float2(5, height() - 20), {ColorId::white, ColorId::black}, format("%s", m_current_entry->tile->resourceName().c_str())); }