github.com/df-mc/dragonfly@v0.9.13/server/item/book_and_quill.go (about)

     1  package item
     2  
     3  import "slices"
     4  
     5  // BookAndQuill is an item used to write WrittenBook(s).
     6  type BookAndQuill struct {
     7  	// Pages represents the pages within the book.
     8  	Pages []string
     9  }
    10  
    11  // MaxCount always returns 1.
    12  func (BookAndQuill) MaxCount() int {
    13  	return 1
    14  }
    15  
    16  // TotalPages returns the total number of pages in the book.
    17  func (b BookAndQuill) TotalPages() int {
    18  	return len(b.Pages)
    19  }
    20  
    21  // Page returns a specific page from the book and true when the page exists. It will otherwise return an empty string
    22  // and false.
    23  func (b BookAndQuill) Page(page int) (string, bool) {
    24  	if page < 0 || len(b.Pages) <= page {
    25  		return "", false
    26  	}
    27  	return b.Pages[page], true
    28  }
    29  
    30  // DeletePage attempts to delete a page from the book.
    31  func (b BookAndQuill) DeletePage(page int) BookAndQuill {
    32  	if page < 0 || page >= 50 {
    33  		panic("invalid page number")
    34  	}
    35  	if _, ok := b.Page(page); !ok {
    36  		panic("cannot delete nonexistent page")
    37  	}
    38  	b.Pages = slices.Delete(b.Pages, page, page+1)
    39  	return b
    40  }
    41  
    42  // InsertPage attempts to insert a page within the book
    43  func (b BookAndQuill) InsertPage(page int, text string) BookAndQuill {
    44  	if page < 0 || page >= 50 {
    45  		panic("invalid page number")
    46  	}
    47  	if len(text) > 256 {
    48  		panic("text longer then 256 bytes")
    49  	}
    50  	if page > len(b.Pages) {
    51  		panic("unable to insert page at invalid position")
    52  	}
    53  	b.Pages = slices.Insert(b.Pages, page, text)
    54  	return b
    55  }
    56  
    57  // SetPage writes a page to the book, if the page doesn't exist it will be created. It will panic if the
    58  // text is longer then 256 characters. It will return a new book representing this data.
    59  func (b BookAndQuill) SetPage(page int, text string) BookAndQuill {
    60  	if page < 0 || page >= 50 {
    61  		panic("invalid page number")
    62  	}
    63  	if len(text) > 256 {
    64  		panic("text longer then 256 bytes")
    65  	}
    66  	if _, ok := b.Page(page); !ok {
    67  		pages := make([]string, page+1)
    68  		copy(pages, b.Pages)
    69  		b.Pages = pages
    70  	}
    71  	b.Pages[page] = text
    72  	return b
    73  }
    74  
    75  // SwapPages swaps two different pages, it will panic if the largest of the two numbers doesn't exist. It will
    76  // return the newly updated pages.
    77  func (b BookAndQuill) SwapPages(pageOne, pageTwo int) BookAndQuill {
    78  	if pageOne < 0 || pageTwo < 0 {
    79  		panic("negative page number")
    80  	}
    81  	if _, ok := b.Page(max(pageOne, pageTwo)); !ok {
    82  		panic("invalid page number")
    83  	}
    84  	temp := b.Pages[pageOne]
    85  	b.Pages[pageOne] = b.Pages[pageTwo]
    86  	b.Pages[pageTwo] = temp
    87  	return b
    88  }
    89  
    90  // DecodeNBT ...
    91  func (b BookAndQuill) DecodeNBT(data map[string]any) any {
    92  	pages, _ := data["pages"].([]any)
    93  	for _, page := range pages {
    94  		if pageData, ok := page.(map[string]any); ok {
    95  			if text, ok := pageData["text"].(string); ok {
    96  				b.Pages = append(b.Pages, text)
    97  			}
    98  		}
    99  	}
   100  	return b
   101  }
   102  
   103  // EncodeNBT ...
   104  func (b BookAndQuill) EncodeNBT() map[string]any {
   105  	pages := make([]any, 0, len(b.Pages))
   106  	for _, page := range b.Pages {
   107  		pages = append(pages, map[string]any{"text": page})
   108  	}
   109  	return map[string]any{"pages": pages}
   110  }
   111  
   112  // EncodeItem ...
   113  func (BookAndQuill) EncodeItem() (name string, meta int16) {
   114  	return "minecraft:writable_book", 0
   115  }
   116  
   117  // max ...
   118  func max(a, b int) int {
   119  	if a > b {
   120  		return a
   121  	}
   122  	return b
   123  }