implemented tokens; alpha testing go
This commit is contained in:
parent
4ba6c9315f
commit
e7081a5320
9 changed files with 218 additions and 96 deletions
|
@ -231,8 +231,6 @@ func (self *GameTableServer) writeToDB(tableMsg *models.TableMessage) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tableMsg.Token.X = nil
|
|
||||||
tableMsg.Token.Y = nil
|
|
||||||
} else if t.X != nil && t.Y != nil {
|
} else if t.X != nil && t.Y != nil {
|
||||||
err := self.dbAdapter.MoveToken(key, t)
|
err := self.dbAdapter.MoveToken(key, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -273,11 +271,6 @@ func (self *GameTableServer) writeToDB(tableMsg *models.TableMessage) error {
|
||||||
}
|
}
|
||||||
if tableMsg.Token != nil {
|
if tableMsg.Token != nil {
|
||||||
t := tableMsg.Token
|
t := tableMsg.Token
|
||||||
strId := ""
|
|
||||||
if t.Id != nil {
|
|
||||||
strId = *t.Id
|
|
||||||
}
|
|
||||||
fmt.Println(strId +"::" + t.Name + "::" + t.Sprite)
|
|
||||||
if t.Id == nil {
|
if t.Id == nil {
|
||||||
id, err := self.dbAdapter.CreateToken(key, *t)
|
id, err := self.dbAdapter.CreateToken(key, *t)
|
||||||
t.Id = &id
|
t.Id = &id
|
||||||
|
|
|
@ -25,8 +25,8 @@ type Token struct {
|
||||||
H int `json:"h"`
|
H int `json:"h"`
|
||||||
OX int `json:"oX"`
|
OX int `json:"oX"`
|
||||||
OY int `json:"oY"`
|
OY int `json:"oY"`
|
||||||
X *int `json:"x"`
|
X *float64 `json:"x"`
|
||||||
Y *int `json:"y"`
|
Y *float64 `json:"y"`
|
||||||
Active bool `json:"active"`
|
Active bool `json:"active"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,8 +42,8 @@ type Table struct {
|
||||||
type TableMessage struct {
|
type TableMessage struct {
|
||||||
Auth *string `json:"auth,omitempty"`
|
Auth *string `json:"auth,omitempty"`
|
||||||
Key *TableKey `json:"key"`
|
Key *TableKey `json:"key"`
|
||||||
DiceRoll *DiceRoll `json:"diceRoll"`
|
DiceRoll *DiceRoll `json:"diceRoll,omitempty"`
|
||||||
Token *Token `json:"token"`
|
Token *Token `json:"token,omitempty"`
|
||||||
MapImg *string `json:"mapImg"`
|
MapImg *string `json:"mapImg,omitempty"`
|
||||||
AuxMsg *string `json:"auxMsg"`
|
AuxMsg *string `json:"auxMsg,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,24 +290,21 @@ func (self *DbEngine) GetAuxMessage(table models.TableKey) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *DbEngine) CheckToken(table models.TableKey, tokenId string) (bool, bool) {
|
func (self *DbEngine) CheckToken(table models.TableKey, tokenId string) (bool, bool) {
|
||||||
mongoId, err := primitive.ObjectIDFromHex(tokenId)
|
|
||||||
if err != nil {
|
|
||||||
return false, false
|
|
||||||
}
|
|
||||||
tables := self.db.Collection("tables")
|
tables := self.db.Collection("tables")
|
||||||
if tables != nil {
|
if tables != nil {
|
||||||
result := models.Table{}
|
result := models.Table{}
|
||||||
err := tables.FindOne(self.mkCtx(10), bson.D{
|
err := tables.FindOne(self.mkCtx(10), bson.D{
|
||||||
{"name", table.Name},
|
{"name", table.Name},
|
||||||
{"passcode", table.Passcode},
|
{"passcode", table.Passcode},
|
||||||
{"tokens", bson.E{"_id", mongoId}},
|
{"tokens._id", tokenId},
|
||||||
}).Decode(&result)
|
}).Decode(&result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Printf("%v", err)
|
||||||
return false, false
|
return false, false
|
||||||
} else {
|
} else {
|
||||||
active := false
|
active := false
|
||||||
for _, t := range result.Tokens {
|
for _, t := range result.Tokens {
|
||||||
if *t.Id == tokenId && t.Active {
|
if t.Id != nil && *t.Id == tokenId && t.Active {
|
||||||
active = true
|
active = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,10 +341,6 @@ func (self *DbEngine) CreateToken(table models.TableKey, token models.Token) (st
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *DbEngine) ActivateToken(table models.TableKey, tokenId string, active bool) error {
|
func (self *DbEngine) ActivateToken(table models.TableKey, tokenId string, active bool) error {
|
||||||
mongoId, err := primitive.ObjectIDFromHex(tokenId)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
tables := self.db.Collection("tables")
|
tables := self.db.Collection("tables")
|
||||||
if tables != nil {
|
if tables != nil {
|
||||||
var result models.Table
|
var result models.Table
|
||||||
|
@ -356,12 +349,10 @@ func (self *DbEngine) ActivateToken(table models.TableKey, tokenId string, activ
|
||||||
bson.D{
|
bson.D{
|
||||||
{"name", table.Name},
|
{"name", table.Name},
|
||||||
{"passcode", table.Passcode},
|
{"passcode", table.Passcode},
|
||||||
{"tokens", bson.E{"_id", mongoId}},
|
{"tokens._id", tokenId},
|
||||||
},
|
},
|
||||||
bson.D{
|
bson.D{
|
||||||
{"$set", bson.D{{"tokens.$", bson.D{
|
{"$set", bson.D{{"tokens.$.active", active}}},
|
||||||
{"active", active},
|
|
||||||
}}}},
|
|
||||||
},
|
},
|
||||||
).Decode(&result)
|
).Decode(&result)
|
||||||
return err
|
return err
|
||||||
|
@ -370,10 +361,6 @@ func (self *DbEngine) ActivateToken(table models.TableKey, tokenId string, activ
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *DbEngine) MoveToken(table models.TableKey, token models.Token) error {
|
func (self *DbEngine) MoveToken(table models.TableKey, token models.Token) error {
|
||||||
mongoId, err := primitive.ObjectIDFromHex(*token.Id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
tables := self.db.Collection("tables")
|
tables := self.db.Collection("tables")
|
||||||
if tables != nil {
|
if tables != nil {
|
||||||
var result models.Table
|
var result models.Table
|
||||||
|
@ -382,13 +369,10 @@ func (self *DbEngine) MoveToken(table models.TableKey, token models.Token) error
|
||||||
bson.D{
|
bson.D{
|
||||||
{"name", table.Name},
|
{"name", table.Name},
|
||||||
{"passcode", table.Passcode},
|
{"passcode", table.Passcode},
|
||||||
{"tokens", bson.E{"_id", mongoId}},
|
{"tokens._id", token.Id},
|
||||||
},
|
},
|
||||||
bson.D{
|
bson.D{
|
||||||
{"$set", bson.D{{"tokens.$", bson.D{
|
{"$set", bson.D{{"tokens.$.x", token.X}, {"tokens.$.y", token.Y}}},
|
||||||
{"x", token.X},
|
|
||||||
{"y", token.Y},
|
|
||||||
}}}},
|
|
||||||
},
|
},
|
||||||
).Decode(&result)
|
).Decode(&result)
|
||||||
return err
|
return err
|
||||||
|
@ -397,10 +381,7 @@ func (self *DbEngine) MoveToken(table models.TableKey, token models.Token) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *DbEngine) DestroyToken(table models.TableKey, tokenId string) error {
|
func (self *DbEngine) DestroyToken(table models.TableKey, tokenId string) error {
|
||||||
mongoId, err := primitive.ObjectIDFromHex(tokenId)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
tables := self.db.Collection("tables")
|
tables := self.db.Collection("tables")
|
||||||
if tables != nil {
|
if tables != nil {
|
||||||
var result models.Table
|
var result models.Table
|
||||||
|
@ -411,7 +392,7 @@ func (self *DbEngine) DestroyToken(table models.TableKey, tokenId string) error
|
||||||
{"passcode", table.Passcode},
|
{"passcode", table.Passcode},
|
||||||
},
|
},
|
||||||
bson.D{
|
bson.D{
|
||||||
{"$pull", bson.D{{"tokens", bson.D{{"_id", mongoId}}}}},
|
{"$pull", bson.D{{"tokens", bson.D{{"_id", tokenId}}}}},
|
||||||
},
|
},
|
||||||
).Decode(&result)
|
).Decode(&result)
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -43,17 +43,17 @@ async function rebindUi(name, pass) {
|
||||||
document.getElementById("input_table_pass").value = pass;
|
document.getElementById("input_table_pass").value = pass;
|
||||||
dial();
|
dial();
|
||||||
const table = await res.json()
|
const table = await res.json()
|
||||||
infoHtml = "<a href='#' onclick='getTables()'>← table list</a><br>";
|
infoHtml = "<a href='#' onclick='getTables();return false;'>← table list</a><br>";
|
||||||
infoHtml += `<textarea id='auxMsgZone'>${table.auxMsg}</textarea><br><button onclick='publishAuxMsg()'>Set Status</button>`
|
infoHtml += `<textarea id='auxMsgZone'>${table.auxMsg}</textarea><br><button onclick='publishAuxMsg()'>Set Status</button>`
|
||||||
infoHtml += "<button onclick='destroyTable()'>Destroy Table</button><br/>";
|
infoHtml += "<button onclick='destroyTable()'>Destroy Table</button><br/>";
|
||||||
infoHtml += "<input id='map_img_upload' type='file'/><button onclick='uploadMapImg()'>Upload Map</button><br/>"
|
infoHtml += "<input id='map_img_upload' type='file'/><button onclick='uploadMapImg()'>Upload Map</button><br/>"
|
||||||
if (mapImgs.ok) {
|
if (mapImgs.ok) {
|
||||||
infoHtml += "<label>Available Maps</label>";
|
infoHtml += "<label>Available Maps</label>";
|
||||||
const imgs = await mapImgs.json();
|
const imgs = await mapImgs.json();
|
||||||
infoHtml += "<ul>";
|
infoHtml += "<ul class='two_btn_list'>";
|
||||||
for (const i of imgs) {
|
for (const i of imgs) {
|
||||||
const parts = i.split("/");
|
const parts = i.split("/");
|
||||||
infoHtml += `<li>${parts[parts.length - 1]} <a href="${i}" target="_blank">view</a> <button onclick="sendMapImg('${i}');">Set</button> <button onclick="deleteImg('${i}')">Delete</button></li>\n`;
|
infoHtml += `<li><a href="${i}" target="_blank">${parts[parts.length - 1]}</a> <button onclick="sendMapImg('${i}');">Set</button> <button onclick="deleteImg('${i}')">Delete</button></li>\n`;
|
||||||
}
|
}
|
||||||
infoHtml += "</ul>";
|
infoHtml += "</ul>";
|
||||||
} else {
|
} else {
|
||||||
|
@ -65,10 +65,10 @@ async function rebindUi(name, pass) {
|
||||||
if (tokenImgs.ok) {
|
if (tokenImgs.ok) {
|
||||||
tokenListHTML += "<label>Available Sprites</label>";
|
tokenListHTML += "<label>Available Sprites</label>";
|
||||||
const tokens = await tokenImgs.json();
|
const tokens = await tokenImgs.json();
|
||||||
tokenListHTML += "<ul>";
|
tokenListHTML += "<ul class='single_btn_list'>";
|
||||||
for (const t of tokens) {
|
for (const t of tokens) {
|
||||||
const parts = t.split("/");
|
const parts = t.split("/");
|
||||||
tokenListHTML += `<li>${parts[parts.length - 1]} <a href="${t}" target="_blank">view</a> <button onclick="deleteImg('${t}')">Delete</button></li>\n`
|
tokenListHTML += `<li><a href="${t}" target="_blank">${parts[parts.length - 1]}</a> <button onclick="deleteImg('${t}')">Delete</button></li>\n`
|
||||||
}
|
}
|
||||||
tokenListHTML += "</ul>";
|
tokenListHTML += "</ul>";
|
||||||
fillSpriteDropdown(tokens);
|
fillSpriteDropdown(tokens);
|
||||||
|
@ -156,6 +156,7 @@ function scaleSpritePreview(source) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawTokenOrigin() {
|
function drawTokenOrigin() {
|
||||||
|
if (tokenSpriteDropdown.selectedIndex >= 0) {
|
||||||
const img = previewZone.children[0];
|
const img = previewZone.children[0];
|
||||||
const x = Number(tokenWidth.value) / Number(tokenCX.value);
|
const x = Number(tokenWidth.value) / Number(tokenCX.value);
|
||||||
const y = Number(tokenHeight.value) / Number(tokenCY.value);
|
const y = Number(tokenHeight.value) / Number(tokenCY.value);
|
||||||
|
@ -173,6 +174,7 @@ function drawTokenOrigin() {
|
||||||
} else {
|
} else {
|
||||||
previewZone.appendChild(originImg);
|
previewZone.appendChild(originImg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function reinitializeSpritePreview() {
|
function reinitializeSpritePreview() {
|
||||||
|
@ -189,11 +191,8 @@ function reinitializeSpritePreview() {
|
||||||
tokenHeight.value = h;
|
tokenHeight.value = h;
|
||||||
scaleSpritePreview();
|
scaleSpritePreview();
|
||||||
}
|
}
|
||||||
if (previewZone.children.length) {
|
previewZone.innerHTML = "";
|
||||||
previewZone.replaceChild(img, previewZone.children[0]);
|
|
||||||
} else {
|
|
||||||
previewZone.appendChild(img);
|
previewZone.appendChild(img);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createToken() {
|
function createToken() {
|
||||||
|
@ -233,6 +232,46 @@ function createToken() {
|
||||||
setErr("All token fields are required");
|
setErr("All token fields are required");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function destroyToken(id) {
|
||||||
|
const existing = tokens.find(t=>t.t.id == id);
|
||||||
|
if (existing) {
|
||||||
|
const self = Object.assign({}, existing.t);
|
||||||
|
self.active = false;
|
||||||
|
self.x = null;
|
||||||
|
self.y = null;
|
||||||
|
sendToken(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function previewExistingToken(id) {
|
||||||
|
const existing = tokens.find(t=>t.t.id == id);
|
||||||
|
if (existing) {
|
||||||
|
tokenWidth.value = existing.t.w;
|
||||||
|
tokenHeight.value = existing.t.h;
|
||||||
|
tokenCX.value = existing.t.oX;
|
||||||
|
tokenCY.value = existing.t.oY;
|
||||||
|
tokenName.value = existing.t.name;
|
||||||
|
for (let i = 0; i < tokenSpriteDropdown.options.length; i++) {
|
||||||
|
if (tokenSpriteDropdown.options[i].value == existing.t.sprite) {
|
||||||
|
tokenSpriteDropdown.selectedIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reinitializeSpritePreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTokenMasterList() {
|
||||||
|
if (tokenZone) {
|
||||||
|
let tokenMasterListHTML = "<label>Available Tokens</label><br/><ul class='single_btn_list'>";
|
||||||
|
for (const t of tokens) {
|
||||||
|
tokenMasterListHTML += `<li><a href="#" onclick="previewExistingToken('${t.t.id}');return false">${t.t.name}</a><button onclick="destroyToken('${t.t.id}')">Destroy</button></li>\n`;
|
||||||
|
}
|
||||||
|
tokenMasterListHTML += "</ul>";
|
||||||
|
tokenZone.innerHTML = tokenMasterListHTML;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function publishAuxMsg() {
|
function publishAuxMsg() {
|
||||||
const txtArea = document.getElementById("auxMsgZone");
|
const txtArea = document.getElementById("auxMsgZone");
|
||||||
if (txtArea != null) {
|
if (txtArea != null) {
|
||||||
|
@ -248,12 +287,6 @@ function sendToken(t) {
|
||||||
publish({token: t, auth: adminToken.access_token});
|
publish({token: t, auth: adminToken.access_token});
|
||||||
}
|
}
|
||||||
|
|
||||||
function revokeToken(t) {
|
|
||||||
t.x = null;
|
|
||||||
t.y = null;
|
|
||||||
sendToken(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function uploadMapImg() {
|
async function uploadMapImg() {
|
||||||
try {
|
try {
|
||||||
var input = document.getElementById("map_img_upload");
|
var input = document.getElementById("map_img_upload");
|
||||||
|
@ -391,6 +424,7 @@ async function doLogin() {
|
||||||
getTables();
|
getTables();
|
||||||
adminWrapper.style.display="inline";
|
adminWrapper.style.display="inline";
|
||||||
adminZone.style.display = "block";
|
adminZone.style.display = "block";
|
||||||
|
closeErr();
|
||||||
} else {
|
} else {
|
||||||
setErr("Incorrect credentials");
|
setErr("Incorrect credentials");
|
||||||
}
|
}
|
||||||
|
@ -430,11 +464,19 @@ function setTableCreateFormVisible(v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setTokenCreateFormVisible(v) {
|
function setTokenCreateFormVisible(v) {
|
||||||
if (createTokenForm) {
|
if (createTokenForm && tokenZone) {
|
||||||
createTokenForm.style.display = v ? "block" : "none";
|
if (v) {
|
||||||
|
// clear the form when displaying because we may have values from a preview of an existing token
|
||||||
|
tokenWidth.value = "";
|
||||||
|
tokenHeight.value = "";
|
||||||
|
tokenCX.value = "";
|
||||||
|
tokenCY.value = "";
|
||||||
|
tokenName.value = "";
|
||||||
|
tokenSpriteDropdown.selectedIndex = 0;
|
||||||
}
|
}
|
||||||
if (!v) {
|
createTokenForm.style.display = v ? "block" : "none";
|
||||||
// clear the form
|
tokenZone.style.display = v ? "none" : "inline";
|
||||||
|
reinitializeSpritePreview();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,8 +106,8 @@
|
||||||
<label>cY<input type="number" id="token_cy" min="0" max="9999" onchange="previewSprite(this)"/></label><br/>
|
<label>cY<input type="number" id="token_cy" min="0" max="9999" onchange="previewSprite(this)"/></label><br/>
|
||||||
<button type="submit" onclick="createToken()">Create</button>
|
<button type="submit" onclick="createToken()">Create</button>
|
||||||
<button onclick="setTokenCreateFormVisible(false)">Cancel</button>
|
<button onclick="setTokenCreateFormVisible(false)">Cancel</button>
|
||||||
<div id="tokenPreview_zone"></div>
|
|
||||||
</form>
|
</form>
|
||||||
|
<div id="tokenPreview_zone"></div>
|
||||||
<div id="tokenZone"></div>
|
<div id="tokenZone"></div>
|
||||||
</details><br/>
|
</details><br/>
|
||||||
<details id="admin_sprite_win" class="ui_win admin_win"><summary>sprites</summary>
|
<details id="admin_sprite_win" class="ui_win admin_win"><summary>sprites</summary>
|
||||||
|
|
|
@ -19,10 +19,8 @@ function initializeMap(mapImgUrl) {
|
||||||
if (init) {
|
if (init) {
|
||||||
map.setView([0,0], 2);
|
map.setView([0,0], 2);
|
||||||
}
|
}
|
||||||
while (tokens.some(t=>t)) {
|
/*
|
||||||
tokens[0].m.removeFrom(map);
|
*/
|
||||||
tokens.shift();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this works but assumes the map is square (reasonable limitation I think)
|
// this works but assumes the map is square (reasonable limitation I think)
|
||||||
|
@ -30,11 +28,58 @@ function resizeMarkers() {
|
||||||
tokens.forEach(t=>{
|
tokens.forEach(t=>{
|
||||||
const icon = t.m.options.icon;
|
const icon = t.m.options.icon;
|
||||||
const scaleFactor = mapImg._image.clientWidth / mapImg._image.naturalWidth;
|
const scaleFactor = mapImg._image.clientWidth / mapImg._image.naturalWidth;
|
||||||
icon.options.iconSize = [scaleFactor * t.sz[0], scaleFactor * t.sz[1]];
|
icon.options.iconSize = [scaleFactor * t.t.w, scaleFactor * t.t.h];
|
||||||
|
icon.options.iconAnchor = [scaleFactor * t.t.oX, scaleFactor * t.t.oY];
|
||||||
t.m.setIcon(icon);
|
t.m.setIcon(icon);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function processTokens(tokenChanges) {
|
||||||
|
for (const t of tokenChanges) {
|
||||||
|
const i = tokens.findIndex(tk=>tk.t.id == t.id);
|
||||||
|
if (i >= 0) {
|
||||||
|
const self = tokens[i];
|
||||||
|
// token was made active
|
||||||
|
if (t.x != null && t.y != null && !self.t.active && t.active) {
|
||||||
|
self.t.active = true;
|
||||||
|
self.m.addTo(map);
|
||||||
|
// token was made inactive
|
||||||
|
} else if (t.x != null && t.y != null && self.t.active && !t.active) {
|
||||||
|
self.t.active = false;
|
||||||
|
self.m.removeFrom(map);
|
||||||
|
// token was destroyed
|
||||||
|
} else if (t.x == null && t.y == null) {
|
||||||
|
self.m.removeFrom(map);
|
||||||
|
tokens.splice(i, 1);
|
||||||
|
// token was moved
|
||||||
|
} else {
|
||||||
|
self.t.x = t.x;
|
||||||
|
self.t.y = t.y;
|
||||||
|
self.m.setLatLng([t.y, t.x]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (t.x != null && t.y != null) {
|
||||||
|
const self = NewToken(t);
|
||||||
|
tokens.push(self);
|
||||||
|
if (t.active) {
|
||||||
|
self.m.addTo(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resizeMarkers();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleActive(tokenId) {
|
||||||
|
const existing = tokens.find(t=>t.t.id == tokenId);
|
||||||
|
if (existing) {
|
||||||
|
const self = Object.assign({}, existing.t);
|
||||||
|
self.active = !self.active;
|
||||||
|
console.log(self);
|
||||||
|
publish({token: self});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getCascadingPos() {
|
function getCascadingPos() {
|
||||||
const topLeft = [0,0];
|
const topLeft = [0,0];
|
||||||
const n = tokens.length;
|
const n = tokens.length;
|
||||||
|
@ -43,18 +88,35 @@ function getCascadingPos() {
|
||||||
return topLeft;
|
return topLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
function NewToken(w, h, oX, oY, img, name, x, y) {
|
function moveToken(id) {
|
||||||
return {
|
const existing = tokens.find(t=>t.t.id == id);
|
||||||
sz: [w, h],
|
if (existing) {
|
||||||
m: L.marker((x && y) ? [y,x] : getCascadingPos(), {
|
const self = Object.assign({}, existing.t);
|
||||||
|
const realPos = existing.m.getLatLng();
|
||||||
|
self.x = realPos.lng;
|
||||||
|
self.y = realPos.lat;
|
||||||
|
console.log(self);
|
||||||
|
publish({token: self});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function NewToken(token) {
|
||||||
|
const marker = L.marker([token.y,token.x], {
|
||||||
icon: L.icon({
|
icon: L.icon({
|
||||||
iconUrl: img,
|
iconUrl: token.sprite,
|
||||||
iconSize: [w,h],
|
iconSize: [token.w,token.h],
|
||||||
|
iconAnchor: [token.oX, token.oY]
|
||||||
}),
|
}),
|
||||||
title: name,
|
title: token.name,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
autoPan: true
|
autoPan: true
|
||||||
}),
|
});
|
||||||
|
|
||||||
|
marker.on("moveend", ()=>{moveToken(token.id)});
|
||||||
|
|
||||||
|
return {
|
||||||
|
t: token,
|
||||||
|
m: marker,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,9 @@ function formatDice(r) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
function logDice(dice, many) {
|
function logDice(dice) {
|
||||||
const diceLog = document.getElementById("dice_log");
|
const diceLog = document.getElementById("dice_log");
|
||||||
if (!many) {
|
if (!Array.isArray(dice)) {
|
||||||
dice = [ dice ];
|
dice = [ dice ];
|
||||||
} else {
|
} else {
|
||||||
if (diceLog) {
|
if (diceLog) {
|
||||||
|
@ -58,19 +58,45 @@ function setAuxMsg(msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateTokens(tokens) {
|
||||||
|
// update internal token array and map
|
||||||
|
processTokens(tokens);
|
||||||
|
// update token select window
|
||||||
|
renderTokenSelect();
|
||||||
|
// if admin, update token master list
|
||||||
|
renderTokenMasterList();
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTokenSelect() {
|
||||||
|
const tokenSelect = document.getElementById("token_select");
|
||||||
|
let tokenSelectHTML = "<ul class='single_btn_list'>";
|
||||||
|
for (const t of tokens) {
|
||||||
|
tokenSelectHTML += `<li><a target="_blank" href="${t.t.sprite}">${t.t.name}</a><button onclick="toggleActive('${t.t.id}')">${(t.t.active ? "Deactivate" : "Activate")}</button></li>\n`;
|
||||||
|
}
|
||||||
|
tokenSelectHTML += "</ul>";
|
||||||
|
tokenSelect.innerHTML = tokenSelectHTML;
|
||||||
|
}
|
||||||
|
|
||||||
function makeUpToDate(table) {
|
function makeUpToDate(table) {
|
||||||
if (table) {
|
if (table) {
|
||||||
if (table.diceRolls) {
|
// map image has to be set before tokens can be handled!
|
||||||
logDice(table.diceRolls, true);
|
|
||||||
} else if (table.diceRoll) {
|
|
||||||
logDice(table.diceRoll, false);
|
|
||||||
}
|
|
||||||
if (table.mapImg) {
|
if (table.mapImg) {
|
||||||
setMapImg(table.mapImg);
|
setMapImg(table.mapImg);
|
||||||
}
|
}
|
||||||
if (table.auxMsg) {
|
if (table.auxMsg) {
|
||||||
setAuxMsg(table.auxMsg);
|
setAuxMsg(table.auxMsg);
|
||||||
}
|
}
|
||||||
|
if (table.diceRolls) {
|
||||||
|
logDice(table.diceRolls);
|
||||||
|
} else if (table.diceRoll) {
|
||||||
|
logDice([table.diceRoll]);
|
||||||
|
}
|
||||||
|
if (table.tokens) {
|
||||||
|
updateTokens(table.tokens);
|
||||||
|
} else if (table.token) {
|
||||||
|
updateTokens([table.token]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,6 +135,10 @@ function dial() {
|
||||||
tabletop.style.display = "none";
|
tabletop.style.display = "none";
|
||||||
}
|
}
|
||||||
table = null;
|
table = null;
|
||||||
|
while (tokens.some(t=>t)) {
|
||||||
|
tokens[0].m.removeFrom(map);
|
||||||
|
tokens.shift();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
conn.addEventListener("open", e => {
|
conn.addEventListener("open", e => {
|
||||||
|
@ -126,7 +156,7 @@ function dial() {
|
||||||
conn.addEventListener("message", e => {
|
conn.addEventListener("message", e => {
|
||||||
const data = JSON.parse(e.data);
|
const data = JSON.parse(e.data);
|
||||||
if (table == null) {
|
if (table == null) {
|
||||||
// first fetch comes from mongo, so the rolls array in each diceRoll is a byte array and needs to be decoded
|
// dicerolls are treated as a byte array when marshalling to json, so we have to decode them
|
||||||
data.diceRolls.forEach(r=>{
|
data.diceRolls.forEach(r=>{
|
||||||
r.roll = Uint8Array.from(atob(r.roll), c => c.charCodeAt(0))
|
r.roll = Uint8Array.from(atob(r.roll), c => c.charCodeAt(0))
|
||||||
})
|
})
|
||||||
|
|
|
@ -24,6 +24,7 @@ body {
|
||||||
background: url('./bg.png');
|
background: url('./bg.png');
|
||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
|
font-family: sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
|
@ -150,6 +151,7 @@ pre {
|
||||||
|
|
||||||
.ui_win ul {
|
.ui_win ul {
|
||||||
max-height: 10em;
|
max-height: 10em;
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#admin_section {
|
#admin_section {
|
||||||
|
@ -159,6 +161,9 @@ pre {
|
||||||
.admin_win {
|
.admin_win {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.admin_win summary {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
#map {
|
#map {
|
||||||
position:fixed;
|
position:fixed;
|
||||||
|
@ -183,3 +188,13 @@ nav {
|
||||||
#tokenPreview_zone {
|
#tokenPreview_zone {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.single_btn_list li {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.two_btn_list li {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr auto auto;
|
||||||
|
}
|
|
@ -20,7 +20,6 @@ function saveName() {
|
||||||
console.log("saving username");
|
console.log("saving username");
|
||||||
const username = document.getElementById("name_entry");
|
const username = document.getElementById("name_entry");
|
||||||
if (username) {
|
if (username) {
|
||||||
console.log(username.value + "input found");
|
|
||||||
document.cookie = "username=" + username.value;
|
document.cookie = "username=" + username.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue