552 lines
21 KiB
Go
552 lines
21 KiB
Go
package levels
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/inkyblackness/imgui-go/v3"
|
|
|
|
"github.com/inkyblackness/hacked/editor/graphics"
|
|
"github.com/inkyblackness/hacked/editor/render"
|
|
"github.com/inkyblackness/hacked/editor/values"
|
|
"github.com/inkyblackness/hacked/ss1/content/archive/level"
|
|
"github.com/inkyblackness/hacked/ss1/content/bitmap"
|
|
"github.com/inkyblackness/hacked/ss1/content/text"
|
|
"github.com/inkyblackness/hacked/ss1/edit"
|
|
"github.com/inkyblackness/hacked/ss1/edit/undoable/cmd"
|
|
"github.com/inkyblackness/hacked/ss1/resource"
|
|
"github.com/inkyblackness/hacked/ss1/world"
|
|
"github.com/inkyblackness/hacked/ss1/world/ids"
|
|
)
|
|
|
|
// TilesView is for tile properties.
|
|
type TilesView struct {
|
|
editor *edit.LevelEditorService
|
|
textCache *text.Cache
|
|
textureCache *graphics.TextureCache
|
|
|
|
guiScale float32
|
|
registry cmd.Registry
|
|
model tilesViewModel
|
|
}
|
|
|
|
// NewTilesView returns a new instance.
|
|
func NewTilesView(editor *edit.LevelEditorService,
|
|
guiScale float32, textCache *text.Cache, textureCache *graphics.TextureCache, registry cmd.Registry) *TilesView {
|
|
view := &TilesView{
|
|
editor: editor,
|
|
textCache: textCache,
|
|
textureCache: textureCache,
|
|
|
|
guiScale: guiScale,
|
|
model: freshTilesViewModel(),
|
|
registry: registry,
|
|
}
|
|
return view
|
|
}
|
|
|
|
// WindowOpen returns the flag address, to be used with the main menu.
|
|
func (view *TilesView) WindowOpen() *bool {
|
|
return &view.model.windowOpen
|
|
}
|
|
|
|
// TextureDisplay returns the current setting which textures should be displayed.
|
|
func (view TilesView) TextureDisplay() TextureDisplay {
|
|
return view.model.textureDisplay
|
|
}
|
|
|
|
// ColorDisplay returns the current setting which colors should be displayed.
|
|
func (view TilesView) ColorDisplay() ColorDisplay {
|
|
lvl := view.editor.Level()
|
|
if lvl.IsCyberspace() {
|
|
return view.model.cyberColorDisplay
|
|
}
|
|
return view.model.shadowDisplay
|
|
}
|
|
|
|
// Render renders the view.
|
|
func (view *TilesView) Render() {
|
|
if view.model.restoreFocus {
|
|
imgui.SetNextWindowFocus()
|
|
view.model.restoreFocus = false
|
|
view.model.windowOpen = true
|
|
}
|
|
if view.model.windowOpen {
|
|
lvl := view.editor.Level()
|
|
tiles := view.editor.Tiles()
|
|
readOnly := view.editor.IsReadOnly()
|
|
title := fmt.Sprintf("Level Tiles, %d selected", len(tiles))
|
|
if readOnly {
|
|
title += hintReadOnly
|
|
}
|
|
imgui.SetNextWindowSizeV(imgui.Vec2{X: 400 * view.guiScale, Y: 500 * view.guiScale}, imgui.ConditionFirstUseEver)
|
|
if imgui.BeginV(title+"###Level Tiles", view.WindowOpen(), 0) {
|
|
view.renderContent(lvl, tiles, readOnly)
|
|
}
|
|
imgui.End()
|
|
}
|
|
}
|
|
|
|
func (view *TilesView) renderContent(lvl *level.Level, tiles []*level.TileMapEntry, readOnly bool) {
|
|
isCyberspace := lvl.IsCyberspace()
|
|
tileTypeUnifier := values.NewUnifier()
|
|
floorHeightUnifier := values.NewUnifier()
|
|
ceilingHeightUnifier := values.NewUnifier()
|
|
slopeHeightUnifier := values.NewUnifier()
|
|
slopeControlUnifier := values.NewUnifier()
|
|
musicZoneUnifier := values.NewUnifier()
|
|
|
|
floorPaletteIndexUnifier := values.NewUnifier()
|
|
ceilingPaletteIndexUnifier := values.NewUnifier()
|
|
flightPullTypeUnifier := values.NewUnifier()
|
|
gameOfLightStateUnifier := values.NewUnifier()
|
|
|
|
floorTextureIndexUnifier := values.NewUnifier()
|
|
floorTextureRotationsUnifier := values.NewUnifier()
|
|
ceilingTextureIndexUnifier := values.NewUnifier()
|
|
ceilingTextureRotationsUnifier := values.NewUnifier()
|
|
wallTextureIndexUnifier := values.NewUnifier()
|
|
wallTextureOffsetUnifier := values.NewUnifier()
|
|
useAdjacentWallTextureUnifier := values.NewUnifier()
|
|
wallTexturePatternUnifier := values.NewUnifier()
|
|
floorLightUnifier := values.NewUnifier()
|
|
floorLightDeltaUnifier := values.NewUnifier()
|
|
ceilingLightUnifier := values.NewUnifier()
|
|
ceilingLightDeltaUnifier := values.NewUnifier()
|
|
deconstructedUnifier := values.NewUnifier()
|
|
perildUnifier := values.NewUnifier()
|
|
floorHazardUnifier := values.NewUnifier()
|
|
ceilingHazardUnifier := values.NewUnifier()
|
|
|
|
for _, tile := range tiles {
|
|
tileTypeUnifier.Add(tile.Type)
|
|
floorHeightUnifier.Add(tile.Floor.AbsoluteHeight())
|
|
ceilingHeightUnifier.Add(tile.Ceiling.AbsoluteHeight())
|
|
slopeHeightUnifier.Add(tile.SlopeHeight)
|
|
slopeControlUnifier.Add(tile.Flags.SlopeControl())
|
|
musicZoneUnifier.Add(tile.Flags.MusicZone())
|
|
perildUnifier.Add(tile.Flags.Peril())
|
|
if isCyberspace {
|
|
floorPaletteIndexUnifier.Add(tile.TextureInfo.FloorPaletteIndex())
|
|
ceilingPaletteIndexUnifier.Add(tile.TextureInfo.CeilingPaletteIndex())
|
|
flightPullTypeUnifier.Add(tile.Flags.ForCyberspace().FlightPull())
|
|
gameOfLightStateUnifier.Add(tile.Flags.ForCyberspace().GameOfLifeState())
|
|
} else {
|
|
flags := tile.Flags.ForRealWorld()
|
|
floorTextureIndexUnifier.Add(int(tile.TextureInfo.FloorTextureIndex()))
|
|
floorTextureRotationsUnifier.Add(tile.Floor.TextureRotations())
|
|
ceilingTextureIndexUnifier.Add(int(tile.TextureInfo.CeilingTextureIndex()))
|
|
ceilingTextureRotationsUnifier.Add(tile.Ceiling.TextureRotations())
|
|
wallTextureIndexUnifier.Add(int(tile.TextureInfo.WallTextureIndex()))
|
|
wallTextureOffsetUnifier.Add(flags.WallTextureOffset())
|
|
useAdjacentWallTextureUnifier.Add(flags.UseAdjacentWallTexture())
|
|
wallTexturePatternUnifier.Add(flags.WallTexturePattern())
|
|
floorLightUnifier.Add(level.GradesOfShadow - 1 - flags.FloorShadow())
|
|
floorLightDeltaUnifier.Add(tile.LightDelta.OfFloor())
|
|
ceilingLightUnifier.Add(level.GradesOfShadow - 1 - flags.CeilingShadow())
|
|
ceilingLightDeltaUnifier.Add(tile.LightDelta.OfCeiling())
|
|
deconstructedUnifier.Add(flags.Deconstructed())
|
|
floorHazardUnifier.Add(tile.Floor.HasHazard())
|
|
ceilingHazardUnifier.Add(tile.Ceiling.HasHazard())
|
|
}
|
|
}
|
|
|
|
imgui.PushItemWidth(-250 * view.guiScale)
|
|
|
|
_, _, levelHeight := lvl.Size()
|
|
tileHeightFormatter := tileHeightFormatterFor(levelHeight)
|
|
|
|
tileTypes := level.TileTypes()
|
|
values.RenderUnifiedCombo(readOnly, "Tile Type", tileTypeUnifier,
|
|
func(u values.Unifier) int { return int(u.Unified().(level.TileType)) },
|
|
func(value int) string { return tileTypes[value].String() },
|
|
len(tileTypes),
|
|
func(newValue int) { view.changeTiles(setTileTypeTo(level.TileType(newValue))) })
|
|
values.RenderUnifiedSliderInt(readOnly, "Floor Height", floorHeightUnifier,
|
|
func(u values.Unifier) int { return int(u.Unified().(level.TileHeightUnit)) },
|
|
tileHeightFormatter,
|
|
0, int(level.TileHeightUnitMax)-1,
|
|
func(newValue int) { view.changeTiles(setFloorHeightTo(level.TileHeightUnit(newValue))) })
|
|
values.RenderUnifiedSliderInt(readOnly, "Ceiling Height (abs)", ceilingHeightUnifier,
|
|
func(u values.Unifier) int { return int(u.Unified().(level.TileHeightUnit)) },
|
|
tileHeightFormatter,
|
|
1, int(level.TileHeightUnitMax),
|
|
func(newValue int) { view.changeTiles(setCeilingHeightTo(level.TileHeightUnit(newValue))) })
|
|
values.RenderUnifiedSliderInt(readOnly, "Slope Height", slopeHeightUnifier,
|
|
func(u values.Unifier) int { return int(u.Unified().(level.TileHeightUnit)) },
|
|
tileHeightFormatter,
|
|
0, int(level.TileHeightUnitMax)-1,
|
|
func(newValue int) { view.changeTiles(setSlopeHeightTo(level.TileHeightUnit(newValue))) })
|
|
slopeControls := level.TileSlopeControls()
|
|
values.RenderUnifiedCombo(readOnly, "Slope Control", slopeControlUnifier,
|
|
func(u values.Unifier) int { return int(u.Unified().(level.TileSlopeControl)) },
|
|
func(value int) string { return slopeControls[value].String() },
|
|
len(slopeControls),
|
|
func(newValue int) { view.changeTiles(setSlopeControlTo(slopeControls[newValue])) })
|
|
musicZones := level.TileMusicZones()
|
|
values.RenderUnifiedCombo(readOnly, "Music Zone", musicZoneUnifier,
|
|
func(u values.Unifier) int { return int(u.Unified().(level.TileMusicZone)) },
|
|
func(value int) string { return musicZones[value].String() },
|
|
len(musicZones),
|
|
func(newValue int) { view.changeTiles(setMusicZoneTo(musicZones[newValue])) })
|
|
values.RenderUnifiedCheckboxCombo(readOnly, "Music Peril", perildUnifier,
|
|
func(newValue bool) { view.changeTiles(setPerilTo(newValue)) })
|
|
|
|
imgui.Separator()
|
|
|
|
if isCyberspace {
|
|
if imgui.BeginCombo("Color View", view.model.cyberColorDisplay.String()) {
|
|
displays := ColorDisplays()
|
|
for _, display := range displays {
|
|
displayString := display.String()
|
|
|
|
if imgui.SelectableV(displayString, display == view.model.cyberColorDisplay, 0, imgui.Vec2{}) {
|
|
view.model.cyberColorDisplay = display
|
|
}
|
|
}
|
|
imgui.EndCombo()
|
|
}
|
|
|
|
values.RenderUnifiedSliderInt(readOnly, "Floor Color", floorPaletteIndexUnifier,
|
|
func(u values.Unifier) int { return int(u.Unified().(byte)) },
|
|
func(value int) string { return "%d" },
|
|
0, bitmap.PaletteSize-1,
|
|
func(newValue int) { view.changeTiles(setFloorPaletteIndexTo(newValue)) })
|
|
values.RenderUnifiedSliderInt(readOnly, "Ceiling Color", ceilingPaletteIndexUnifier,
|
|
func(u values.Unifier) int { return int(u.Unified().(byte)) },
|
|
func(value int) string { return "%d" },
|
|
0, bitmap.PaletteSize-1,
|
|
func(newValue int) { view.changeTiles(setCeilingPaletteIndexTo(newValue)) })
|
|
|
|
imgui.Separator()
|
|
|
|
flightPulls := level.CyberspaceFlightPulls()
|
|
values.RenderUnifiedCombo(readOnly, "Flight Pull Type", flightPullTypeUnifier,
|
|
func(u values.Unifier) int { return int(u.Unified().(level.CyberspaceFlightPull)) },
|
|
func(value int) string { return flightPulls[value].String() },
|
|
len(flightPulls),
|
|
func(newValue int) { view.changeTiles(setFlightPullTypeTo(flightPulls[newValue])) })
|
|
values.RenderUnifiedSliderInt(readOnly, "Game Of Life State", gameOfLightStateUnifier,
|
|
func(u values.Unifier) int { return u.Unified().(int) },
|
|
func(value int) string { return "%d" },
|
|
0, 3,
|
|
func(newValue int) { view.changeTiles(setGameOfLightStateTo(newValue)) })
|
|
} else {
|
|
atlas := lvl.TextureAtlas()
|
|
|
|
if imgui.BeginCombo("Texture View", view.model.textureDisplay.String()) {
|
|
displays := TextureDisplays()
|
|
for _, display := range displays {
|
|
displayString := display.String()
|
|
|
|
if imgui.SelectableV(displayString, display == view.model.textureDisplay, 0, imgui.Vec2{}) {
|
|
view.model.textureDisplay = display
|
|
}
|
|
}
|
|
imgui.EndCombo()
|
|
}
|
|
|
|
values.RenderUnifiedSliderInt(readOnly, "Floor Texture (atlas index)", floorTextureIndexUnifier,
|
|
func(u values.Unifier) int { return u.Unified().(int) },
|
|
func(value int) string { return "%d" },
|
|
0, level.FloorCeilingTextureLimit-1,
|
|
func(newValue int) { view.changeTiles(setFloorTextureIndexTo(level.AtlasIndex(newValue))) })
|
|
view.renderTextureSelector(readOnly, "Floor Texture", floorTextureIndexUnifier, atlas, 0, level.FloorCeilingTextureLimit-1,
|
|
func(newValue int) { view.changeTiles(setFloorTextureIndexTo(level.AtlasIndex(newValue))) })
|
|
values.RenderUnifiedSliderInt(readOnly, "Floor Texture Rotations", floorTextureRotationsUnifier,
|
|
func(u values.Unifier) int { return u.Unified().(int) },
|
|
func(value int) string { return "%d" },
|
|
0, 3,
|
|
func(newValue int) { view.changeTiles(setFloorTextureRotationsTo(newValue)) })
|
|
|
|
values.RenderUnifiedSliderInt(readOnly, "Ceiling Texture (atlas index)", ceilingTextureIndexUnifier,
|
|
func(u values.Unifier) int { return u.Unified().(int) },
|
|
func(value int) string { return "%d" },
|
|
0, level.FloorCeilingTextureLimit-1,
|
|
func(newValue int) { view.changeTiles(setCeilingTextureIndexTo(level.AtlasIndex(newValue))) })
|
|
view.renderTextureSelector(readOnly, "Ceiling Texture", ceilingTextureIndexUnifier, atlas, 0, level.FloorCeilingTextureLimit-1,
|
|
func(newValue int) { view.changeTiles(setCeilingTextureIndexTo(level.AtlasIndex(newValue))) })
|
|
values.RenderUnifiedSliderInt(readOnly, "Ceiling Texture Rotations", ceilingTextureRotationsUnifier,
|
|
func(u values.Unifier) int { return u.Unified().(int) },
|
|
func(value int) string { return "%d" },
|
|
0, 3,
|
|
func(newValue int) { view.changeTiles(setCeilingTextureRotationsTo(newValue)) })
|
|
|
|
values.RenderUnifiedSliderInt(readOnly, "Wall Texture (atlas index)", wallTextureIndexUnifier,
|
|
func(u values.Unifier) int { return u.Unified().(int) },
|
|
func(value int) string { return "%d" },
|
|
0, len(atlas)-1,
|
|
func(newValue int) { view.changeTiles(setWallTextureIndexTo(level.AtlasIndex(newValue))) })
|
|
view.renderTextureSelector(readOnly, "Wall Texture", wallTextureIndexUnifier, atlas, 0, len(atlas)-1,
|
|
func(newValue int) { view.changeTiles(setWallTextureIndexTo(level.AtlasIndex(newValue))) })
|
|
values.RenderUnifiedSliderInt(readOnly, "Wall Texture Offset", wallTextureOffsetUnifier,
|
|
func(u values.Unifier) int { return int(u.Unified().(level.TileHeightUnit)) },
|
|
tileHeightFormatter,
|
|
0, int(level.TileHeightUnitMax)-1,
|
|
func(newValue int) { view.changeTiles(setWallTextureOffsetTo(level.TileHeightUnit(newValue))) })
|
|
|
|
values.RenderUnifiedCheckboxCombo(readOnly, "Use Adjacent Wall Texture", useAdjacentWallTextureUnifier,
|
|
func(newValue bool) { view.changeTiles(setUseAdjacentWallTextureTo(newValue)) })
|
|
wallTexturePatterns := level.WallTexturePatterns()
|
|
values.RenderUnifiedCombo(readOnly, "Wall Texture Pattern", wallTexturePatternUnifier,
|
|
func(u values.Unifier) int { return int(u.Unified().(level.WallTexturePattern)) },
|
|
func(value int) string { return wallTexturePatterns[value].String() },
|
|
len(wallTexturePatterns),
|
|
func(newValue int) { view.changeTiles(setWallTexturePatternTo(wallTexturePatterns[newValue])) })
|
|
|
|
imgui.Separator()
|
|
|
|
if imgui.BeginCombo("Shadow View", view.model.shadowDisplay.String()) {
|
|
displays := ColorDisplays()
|
|
for _, display := range displays {
|
|
displayString := display.String()
|
|
|
|
if imgui.SelectableV(displayString, display == view.model.shadowDisplay, 0, imgui.Vec2{}) {
|
|
view.model.shadowDisplay = display
|
|
}
|
|
}
|
|
imgui.EndCombo()
|
|
}
|
|
|
|
values.RenderUnifiedSliderInt(readOnly, "Floor Light", floorLightUnifier,
|
|
func(u values.Unifier) int { return u.Unified().(int) },
|
|
func(value int) string { return "%d" },
|
|
0, level.GradesOfShadow-1,
|
|
func(newValue int) { view.changeTiles(setFloorLightTo(newValue)) })
|
|
values.RenderUnifiedSliderInt(readOnly, "Floor Light Delta", floorLightDeltaUnifier,
|
|
func(u values.Unifier) int { return u.Unified().(int) },
|
|
func(value int) string { return "%d" },
|
|
0, level.GradesOfShadow-1,
|
|
func(newValue int) { view.changeTiles(setFloorLightDeltaTo(newValue)) })
|
|
values.RenderUnifiedSliderInt(readOnly, "Ceiling Light", ceilingLightUnifier,
|
|
func(u values.Unifier) int { return u.Unified().(int) },
|
|
func(value int) string { return "%d" },
|
|
0, level.GradesOfShadow-1,
|
|
func(newValue int) { view.changeTiles(setCeilingLightTo(newValue)) })
|
|
values.RenderUnifiedSliderInt(readOnly, "Ceiling Light Delta", ceilingLightDeltaUnifier,
|
|
func(u values.Unifier) int { return u.Unified().(int) },
|
|
func(value int) string { return "%d" },
|
|
0, level.GradesOfShadow-1,
|
|
func(newValue int) { view.changeTiles(setCeilingLightDeltaTo(newValue)) })
|
|
|
|
imgui.Separator()
|
|
|
|
values.RenderUnifiedCheckboxCombo(readOnly, "Deconstructed", deconstructedUnifier,
|
|
func(newValue bool) { view.changeTiles(setDeconstructedTo(newValue)) })
|
|
values.RenderUnifiedCheckboxCombo(readOnly, "Floor Hazard", floorHazardUnifier,
|
|
func(newValue bool) { view.changeTiles(setFloorHazardTo(newValue)) })
|
|
values.RenderUnifiedCheckboxCombo(readOnly, "Ceiling Hazard", ceilingHazardUnifier,
|
|
func(newValue bool) { view.changeTiles(setCeilingHazardTo(newValue)) })
|
|
}
|
|
|
|
imgui.PopItemWidth()
|
|
}
|
|
|
|
func (view *TilesView) renderTextureSelector(readOnly bool, label string, unifier values.Unifier,
|
|
atlas level.TextureAtlas, minIndex, maxIndex int, changeHandler func(int)) {
|
|
selectedIndex := -1
|
|
if unifier.IsUnique() {
|
|
selectedIndex = unifier.Unified().(int)
|
|
}
|
|
|
|
count := maxIndex - minIndex + 1
|
|
if count > len(atlas) {
|
|
count = len(atlas)
|
|
}
|
|
render.TextureSelector(label, -1, view.guiScale, count, selectedIndex-minIndex,
|
|
view.textureCache,
|
|
func(index int) resource.Key {
|
|
return resource.KeyOf(ids.LargeTextures.Plus(int(atlas[minIndex+index])), resource.LangAny, 0)
|
|
},
|
|
func(index int) string { return view.textureName(int(atlas[minIndex+index])) },
|
|
func(index int) {
|
|
if !readOnly {
|
|
changeHandler(index)
|
|
}
|
|
})
|
|
}
|
|
|
|
func (view *TilesView) textureName(index int) string {
|
|
key := resource.KeyOf(ids.TextureNames, resource.LangDefault, index)
|
|
name, err := view.textCache.Text(key)
|
|
suffix := ""
|
|
if err == nil {
|
|
suffix = ": " + name
|
|
}
|
|
return fmt.Sprintf("%3d", index) + suffix
|
|
}
|
|
|
|
func setTileTypeTo(tileType level.TileType) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Type = tileType
|
|
}
|
|
}
|
|
|
|
func setFloorHeightTo(height level.TileHeightUnit) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Floor = tile.Floor.WithAbsoluteHeight(height)
|
|
}
|
|
}
|
|
|
|
func setCeilingHeightTo(height level.TileHeightUnit) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Ceiling = tile.Ceiling.WithAbsoluteHeight(height)
|
|
}
|
|
}
|
|
|
|
func setSlopeHeightTo(height level.TileHeightUnit) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.SlopeHeight = height
|
|
}
|
|
}
|
|
|
|
func setSlopeControlTo(value level.TileSlopeControl) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Flags = tile.Flags.WithSlopeControl(value)
|
|
}
|
|
}
|
|
|
|
func setPerilTo(value bool) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Flags = tile.Flags.WithPeril(value)
|
|
}
|
|
}
|
|
|
|
func setMusicZoneTo(value level.TileMusicZone) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Flags = tile.Flags.WithMusicZone(value)
|
|
}
|
|
}
|
|
|
|
func setFloorTextureIndexTo(value level.AtlasIndex) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.TextureInfo = tile.TextureInfo.WithFloorTextureIndex(value)
|
|
}
|
|
}
|
|
|
|
func setFloorTextureRotationsTo(value int) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Floor = tile.Floor.WithTextureRotations(value)
|
|
}
|
|
}
|
|
|
|
func setCeilingTextureIndexTo(value level.AtlasIndex) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.TextureInfo = tile.TextureInfo.WithCeilingTextureIndex(value)
|
|
}
|
|
}
|
|
|
|
func setCeilingTextureRotationsTo(value int) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Ceiling = tile.Ceiling.WithTextureRotations(value)
|
|
}
|
|
}
|
|
|
|
func setWallTextureIndexTo(value level.AtlasIndex) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.TextureInfo = tile.TextureInfo.WithWallTextureIndex(value)
|
|
}
|
|
}
|
|
|
|
func setWallTextureOffsetTo(value level.TileHeightUnit) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Flags = tile.Flags.ForRealWorld().WithWallTextureOffset(value).AsTileFlag()
|
|
}
|
|
}
|
|
|
|
func setUseAdjacentWallTextureTo(value bool) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Flags = tile.Flags.ForRealWorld().WithUseAdjacentWallTexture(value).AsTileFlag()
|
|
}
|
|
}
|
|
|
|
func setWallTexturePatternTo(value level.WallTexturePattern) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Flags = tile.Flags.ForRealWorld().WithWallTexturePattern(value).AsTileFlag()
|
|
}
|
|
}
|
|
|
|
func setFloorLightTo(value int) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Flags = tile.Flags.ForRealWorld().WithFloorShadow(level.GradesOfShadow - 1 - value).AsTileFlag()
|
|
}
|
|
}
|
|
|
|
func setFloorLightDeltaTo(value int) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.LightDelta = tile.LightDelta.WithFloor(value)
|
|
}
|
|
}
|
|
|
|
func setCeilingLightTo(value int) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Flags = tile.Flags.ForRealWorld().WithCeilingShadow(level.GradesOfShadow - 1 - value).AsTileFlag()
|
|
}
|
|
}
|
|
|
|
func setCeilingLightDeltaTo(value int) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.LightDelta = tile.LightDelta.WithCeiling(value)
|
|
}
|
|
}
|
|
|
|
func setDeconstructedTo(value bool) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Flags = tile.Flags.ForRealWorld().WithDeconstructed(value).AsTileFlag()
|
|
}
|
|
}
|
|
|
|
func setFloorHazardTo(value bool) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Floor = tile.Floor.WithHazard(value)
|
|
}
|
|
}
|
|
|
|
func setCeilingHazardTo(value bool) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Ceiling = tile.Ceiling.WithHazard(value)
|
|
}
|
|
}
|
|
|
|
func setFloorPaletteIndexTo(value int) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.TextureInfo = tile.TextureInfo.WithFloorPaletteIndex(byte(value))
|
|
}
|
|
}
|
|
|
|
func setCeilingPaletteIndexTo(value int) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.TextureInfo = tile.TextureInfo.WithCeilingPaletteIndex(byte(value))
|
|
}
|
|
}
|
|
|
|
func setFlightPullTypeTo(value level.CyberspaceFlightPull) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Flags = tile.Flags.ForCyberspace().WithFlightPull(value).AsTileFlag()
|
|
}
|
|
}
|
|
|
|
func setGameOfLightStateTo(value int) tileMapEntryModifier {
|
|
return func(tile *level.TileMapEntry) {
|
|
tile.Flags = tile.Flags.ForCyberspace().WithGameOfLifeState(value).AsTileFlag()
|
|
}
|
|
}
|
|
|
|
type tileMapEntryModifier func(*level.TileMapEntry)
|
|
|
|
func (view *TilesView) changeTiles(modifier tileMapEntryModifier) {
|
|
err := view.registry.Register(cmd.Named("ChangeTiles"),
|
|
cmd.Forward(view.restoreFocusTask()),
|
|
cmd.Nested(func() error { return view.editor.ChangeTiles(modifier) }),
|
|
cmd.Reverse(view.restoreFocusTask()))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func (view *TilesView) restoreFocusTask() cmd.Task {
|
|
return func(modder world.Modder) error {
|
|
view.model.restoreFocus = true
|
|
return nil
|
|
}
|
|
}
|