Adding modding folder with a hacked build.
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
package edit
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/inkyblackness/hacked/ss1/content/archive/level"
|
||||
"github.com/inkyblackness/hacked/ss1/edit/undoable/cmd"
|
||||
"github.com/inkyblackness/hacked/ss1/world"
|
||||
)
|
||||
|
||||
type levelSelection struct {
|
||||
tiles map[level.TilePosition]struct{}
|
||||
objects map[level.ObjectID]struct{}
|
||||
}
|
||||
|
||||
func (selection levelSelection) tileList() []level.TilePosition {
|
||||
list := make([]level.TilePosition, 0, len(selection.tiles))
|
||||
for pos := range selection.tiles {
|
||||
list = append(list, pos)
|
||||
}
|
||||
sort.Slice(list, func(a, b int) bool {
|
||||
posA := list[a]
|
||||
posB := list[b]
|
||||
return (posA.Y < posB.Y) || ((posA.Y == posB.Y) && (posA.X < posB.X))
|
||||
})
|
||||
return list
|
||||
}
|
||||
|
||||
func (selection levelSelection) objectList() []level.ObjectID {
|
||||
list := make([]level.ObjectID, 0, len(selection.objects))
|
||||
for id := range selection.objects {
|
||||
list = append(list, id)
|
||||
}
|
||||
sort.Slice(list, func(a, b int) bool { return list[a] < list[b] })
|
||||
return list
|
||||
}
|
||||
|
||||
// LevelInfoProvider returns details on level content.
|
||||
type LevelInfoProvider interface {
|
||||
IsLevelAvailable(index int) bool
|
||||
IsObjectInUse(levelIndex int, id level.ObjectID) bool
|
||||
IsTileOnMap(levelIndex int, pos level.TilePosition) bool
|
||||
}
|
||||
|
||||
// LevelSelectionService keeps track of selections related to levels.
|
||||
type LevelSelectionService struct {
|
||||
provider LevelInfoProvider
|
||||
|
||||
currentLevel int
|
||||
|
||||
levels map[int]*levelSelection
|
||||
}
|
||||
|
||||
// NewLevelSelectionService returns a new instance.
|
||||
func NewLevelSelectionService(provider LevelInfoProvider) *LevelSelectionService {
|
||||
return &LevelSelectionService{
|
||||
provider: provider,
|
||||
currentLevel: 0,
|
||||
levels: make(map[int]*levelSelection),
|
||||
}
|
||||
}
|
||||
|
||||
// CurrentLevelID returns the identifier for the currently selected level.
|
||||
func (service *LevelSelectionService) CurrentLevelID() int {
|
||||
if !service.provider.IsLevelAvailable(service.currentLevel) {
|
||||
return 0
|
||||
}
|
||||
return service.currentLevel
|
||||
}
|
||||
|
||||
// SetCurrentLevelID sets the currently selected level.
|
||||
func (service *LevelSelectionService) SetCurrentLevelID(index int) {
|
||||
service.currentLevel = index
|
||||
}
|
||||
|
||||
// SetCurrentLevelIDTask returns a command task that will set the current level.
|
||||
func (service *LevelSelectionService) SetCurrentLevelIDTask(index int) cmd.Task {
|
||||
return func(modder world.Modder) error {
|
||||
service.SetCurrentLevelID(index)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (service *LevelSelectionService) currentSelection() levelSelection {
|
||||
selection, ok := service.levels[service.currentLevel]
|
||||
if !ok {
|
||||
return levelSelection{}
|
||||
}
|
||||
return *service.cleanSelection(service.currentLevel, selection)
|
||||
}
|
||||
|
||||
func (service *LevelSelectionService) modifiableSelection() *levelSelection {
|
||||
selection, ok := service.levels[service.currentLevel]
|
||||
if !ok {
|
||||
selection = &levelSelection{
|
||||
tiles: make(map[level.TilePosition]struct{}),
|
||||
objects: make(map[level.ObjectID]struct{}),
|
||||
}
|
||||
service.levels[service.currentLevel] = selection
|
||||
}
|
||||
return service.cleanSelection(service.currentLevel, selection)
|
||||
}
|
||||
|
||||
func (service *LevelSelectionService) cleanSelection(levelIndex int, selection *levelSelection) *levelSelection {
|
||||
return service.cleanSelectionTiles(levelIndex, service.cleanSelectionObjects(levelIndex, selection))
|
||||
}
|
||||
|
||||
func (service *LevelSelectionService) cleanSelectionTiles(levelIndex int, selection *levelSelection) *levelSelection {
|
||||
var toDelete []level.TilePosition
|
||||
for pos := range selection.tiles {
|
||||
if !service.provider.IsTileOnMap(levelIndex, pos) {
|
||||
toDelete = append(toDelete, pos)
|
||||
}
|
||||
}
|
||||
for _, pos := range toDelete {
|
||||
delete(selection.tiles, pos)
|
||||
}
|
||||
return selection
|
||||
}
|
||||
|
||||
func (service *LevelSelectionService) cleanSelectionObjects(levelIndex int, selection *levelSelection) *levelSelection {
|
||||
var toDelete []level.ObjectID
|
||||
for id := range selection.objects {
|
||||
if !service.provider.IsObjectInUse(levelIndex, id) {
|
||||
toDelete = append(toDelete, id)
|
||||
}
|
||||
}
|
||||
for _, id := range toDelete {
|
||||
delete(selection.objects, id)
|
||||
}
|
||||
return selection
|
||||
}
|
||||
|
||||
// IsTileSelected returns true if the given tile is currently selected.
|
||||
func (service *LevelSelectionService) IsTileSelected(pos level.TilePosition) bool {
|
||||
_, selected := service.currentSelection().tiles[pos]
|
||||
return selected
|
||||
}
|
||||
|
||||
// CurrentSelectedTiles returns the list of currently selected tiles in the current level.
|
||||
func (service *LevelSelectionService) CurrentSelectedTiles() []level.TilePosition {
|
||||
return service.currentSelection().tileList()
|
||||
}
|
||||
|
||||
// SetCurrentSelectedTiles sets the list of currently selected tiles in the current level.
|
||||
func (service *LevelSelectionService) SetCurrentSelectedTiles(list []level.TilePosition) {
|
||||
selection := service.modifiableSelection()
|
||||
for pos := range selection.tiles {
|
||||
delete(selection.tiles, pos)
|
||||
}
|
||||
for _, pos := range list {
|
||||
selection.tiles[pos] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// AddCurrentSelectedTiles adds the given tile IDs to the list of currently selected in the current level.
|
||||
func (service *LevelSelectionService) AddCurrentSelectedTiles(list []level.TilePosition) {
|
||||
selection := service.modifiableSelection()
|
||||
for _, pos := range list {
|
||||
selection.tiles[pos] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveCurrentSelectedTiles removes the given tile IDs from the list of currently selected in the current level.
|
||||
func (service *LevelSelectionService) RemoveCurrentSelectedTiles(list []level.TilePosition) {
|
||||
selection := service.modifiableSelection()
|
||||
for _, pos := range list {
|
||||
delete(selection.tiles, pos)
|
||||
}
|
||||
}
|
||||
|
||||
// ToggleTileSelection toggles the selection of the given tile IDs in the current level.
|
||||
func (service *LevelSelectionService) ToggleTileSelection(list []level.TilePosition) {
|
||||
selection := service.modifiableSelection()
|
||||
for _, pos := range list {
|
||||
if _, selected := selection.tiles[pos]; selected {
|
||||
delete(selection.tiles, pos)
|
||||
} else {
|
||||
selection.tiles[pos] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NumberOfSelectedObjects returns the number of currently selected objects in the current level.
|
||||
func (service *LevelSelectionService) NumberOfSelectedObjects() int {
|
||||
return len(service.currentSelection().objects)
|
||||
}
|
||||
|
||||
// CurrentSelectedObjects returns the list of currently selected objects in the current level.
|
||||
func (service *LevelSelectionService) CurrentSelectedObjects() []level.ObjectID {
|
||||
return service.currentSelection().objectList()
|
||||
}
|
||||
|
||||
// SetCurrentSelectedObjects sets the list of currently selected objects in the current level.
|
||||
func (service *LevelSelectionService) SetCurrentSelectedObjects(ids []level.ObjectID) {
|
||||
selection := service.modifiableSelection()
|
||||
for id := range selection.objects {
|
||||
delete(selection.objects, id)
|
||||
}
|
||||
for _, id := range ids {
|
||||
selection.objects[id] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// AddCurrentSelectedObjects adds the given object IDs to the list of currently selected in the current level.
|
||||
func (service *LevelSelectionService) AddCurrentSelectedObjects(ids []level.ObjectID) {
|
||||
selection := service.modifiableSelection()
|
||||
for _, id := range ids {
|
||||
selection.objects[id] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveCurrentSelectedObjects removes the given object IDs from the list of currently selected in the current level.
|
||||
func (service *LevelSelectionService) RemoveCurrentSelectedObjects(ids []level.ObjectID) {
|
||||
selection := service.modifiableSelection()
|
||||
for _, id := range ids {
|
||||
delete(selection.objects, id)
|
||||
}
|
||||
}
|
||||
|
||||
// ToggleObjectSelection toggles the selection of the given object IDs in the current level.
|
||||
func (service *LevelSelectionService) ToggleObjectSelection(ids []level.ObjectID) {
|
||||
selection := service.modifiableSelection()
|
||||
for _, id := range ids {
|
||||
if _, selected := selection.objects[id]; selected {
|
||||
delete(selection.objects, id)
|
||||
} else {
|
||||
selection.objects[id] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user