terminei o inventario, falta o de habilidades/poderes '-'

This commit is contained in:
2025-06-24 20:26:59 -03:00
parent 809a9b4efa
commit 5aec4973ec
9 changed files with 440 additions and 168 deletions

View File

@@ -31,6 +31,7 @@ type logEntry struct {
type resp_json struct {
Status string `json:"Status"`
Message string `json:"Message,omitempty"`
PlayerID *int64 `json:"PlayerID,omitempty"`
Logs []logEntry `json:"Logs,omitempty"`
InvPeso int `json:"invPeso,omitempty"`
InvItems []plyInv `json:"InvItems,omitempty"`

View File

@@ -99,6 +99,7 @@ func main() {
e.GET("login", badreq)
e.GET("player", player_data)
e.GET("player/inv", inv_get)
e.POST("player/inv", inv_add)
e.GET("player/inv/del/:id", inv_del)
e.GET("player/inv/use/:id", inv_use)
e.POST("player/update", player_updateInputs)

View File

@@ -197,13 +197,13 @@ func player_data(c echo.Context) error {
}
var foto, nome, vida, descricao string
var conhecimento, level, idade, vd, vdm, destreza, inteligencia, forca, constituicao, carisma, inventario int64
var id, conhecimento, level, idade, vd, vdm, destreza, inteligencia, forca, constituicao, carisma, inventario int64
var altura float64
err = db.QueryRow(`SELECT foto, nome, conhecimento, level, idade, altura, vida, vida_maxima,
err = db.QueryRow(`SELECT id, foto, nome, conhecimento, level, idade, altura, vida, vida_maxima,
destresa, inteligencia, força, constituição, cárisma, inventario, descrição
FROM players WHERE id=? LIMIT 1;`, session["user_id"]).
Scan(&foto, &nome, &conhecimento, &level, &idade, &altura, &vd, &vdm,
Scan(&id, &foto, &nome, &conhecimento, &level, &idade, &altura, &vd, &vdm,
&destreza, &inteligencia, &forca, &constituicao, &carisma, &inventario, &descricao)
if err != nil {
@@ -215,6 +215,7 @@ func player_data(c echo.Context) error {
return c.JSON(http.StatusOK, resp_json{
Status: "Success",
PlayerID: &id,
Foto: foto,
PlayerName: nome,
Conhecimento: &conhecimento,
@@ -263,12 +264,31 @@ func player_update(c echo.Context) error {
if !ok {
return jsonError(c, http.StatusBadRequest, "você passou um parametro invalido, tente novamente com um parametro correto")
}
if atb != "vida" {
query := fmt.Sprintf("UPDATE players SET %s = %s %s 1 WHERE id=?;", field, field, sinal)
if err := updateField(query, session["user_id"]); err != nil {
return jsonError(c, http.StatusInternalServerError, "algo deu errado ao atualizar sua ficha")
}
return jsonSuccess(c, sinal+"1 em "+atb)
}
var life, life_max int
err = db.QueryRow("SELECT vida, vida_maxima FROM players WHERE id=?", session["user_id"]).Scan(&life, &life_max)
if err != nil {
log.Println(err)
return jsonError(c, http.StatusInternalServerError, "algo deu errado ao atualizar sua ficha")
}
if life <= 0 && sinal != "+" {
return jsonError(c, http.StatusBadRequest, "sua vida não pode ficar a baixo de zero")
}
if life >= life_max && sinal != "-" {
return jsonError(c, http.StatusBadRequest, fmt.Sprintf("sua vida maxima é %v, você não pode estar com a vida a cima da maxima", life_max))
}
query := fmt.Sprintf("UPDATE players SET %s = %s %s 1 WHERE id=?;", field, field, sinal)
if err := updateField(query, session["user_id"]); err != nil {
return jsonError(c, http.StatusInternalServerError, "algo deu errado ao atualizar sua ficha")
}
return jsonSuccess(c, sinal+"1 em "+atb)
}
@@ -433,3 +453,62 @@ func inv_use(c echo.Context) error {
}
return jsonSuccess(c, fmt.Sprintf("você gastou seu ultimo %s", item_name))
}
func inv_add(c echo.Context) error {
session, err := requireSession(c)
if err != nil {
return nil
}
if session["playerName"] == "" {
return jsonError(c, http.StatusUnauthorized, "Você precisa estar logado para adicionar itens ao inventário.")
}
nome := c.FormValue("item_name")
durabiliteStr := c.FormValue("durabilite")
peso := c.FormValue("peso")
quantidade := c.FormValue("quantidade")
if anyEmpty(nome, durabiliteStr, peso, quantidade) {
return jsonError(c, http.StatusBadRequest, "Algum parâmetro está faltando ou está vazio. Tente novamente.")
}
durabilite, err := strconv.ParseBool(durabiliteStr)
if err != nil {
return jsonError(c, http.StatusBadRequest, "A durabilidade deve ser 'true' ou 'false'.")
}
row, err := db.Query(fmt.Sprintf("SELECT item_peso FROM inv_%s;", session["playerName"]))
if err != nil {
return jsonError(c, http.StatusInternalServerError, "Erro ao consultar itens do inventário.")
}
defer row.Close()
var total, atualpeso int
for row.Next() {
var itempeso int
if err := row.Scan(&itempeso); err != nil {
return jsonError(c, http.StatusInternalServerError, "Erro ao ler itens do inventário.")
}
total += itempeso
}
err = db.QueryRow("SELECT inventario FROM players WHERE id=?;", session["user_id"]).Scan(&atualpeso)
ps, _ := strconv.Atoi(peso)
if err != nil {
log.Println(err)
return jsonError(c, http.StatusInternalServerError, "Algo deu errado ao verificar o tamanho do seu inventário.")
}
total += ps
if total > atualpeso {
return jsonError(c, http.StatusInternalServerError, fmt.Sprintf("%s é muito pesado para colocar no seu inventário.", nome))
}
_, err = db.Exec(fmt.Sprintf("INSERT INTO inv_%s (item_nome, quantidade, item_peso, item_durabilit) VALUE (?, ?, ?, ?);", session["playerName"]), nome, quantidade, peso, durabilite)
if err != nil {
log.Println(err)
return jsonError(c, http.StatusInternalServerError, fmt.Sprintf("Algo deu errado ao adicionar %s ao seu inventário.", nome))
}
return jsonSuccess(c, fmt.Sprintf("%s %ss foram colocados no seu inventário.", quantidade, nome))
}

View File

@@ -61,6 +61,10 @@ body {
background-color: var(--lines);
}
#btn {
cursor: pointer;
}
a span {
overflow: hidden;
}

View File

@@ -265,6 +265,10 @@
margin: 0 0.5dvh;
}
input[type="text"] {
width: 20%;
}
#btn {
transition: 0.3s;
border-radius: 1dvh;
@@ -279,7 +283,7 @@
}
input[type="number"] {
width: 3dvw;
width: 5dvw;
}
label {
@@ -302,7 +306,8 @@
width: calc(100% - (30% + 25% + 30%));
ul {
height: 100%;
height: 50%;
border-bottom: dotted 2px var(--lines);
overflow-y: scroll;
li {
@@ -320,6 +325,46 @@
}
}
}
hgroup {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
padding: 0;
input {
margin-top: 1dvh;
width: 90%;
border: none;
border-radius: 5px;
padding: 2px;
text-align: center;
background-color: var(--btncolor);
font-size: 1.2em;
}
textarea {
width: 90%;
height: 4dvw;
resize: none;
border: none;
border-radius: 5px;
padding: 2px;
background-color: var(--btncolor);
font-size: 1.2em;
margin-top: 0.5dvh;
}
a {
margin-top: 0.5dvh;
background-color: var(--btncolor);
width: 90%;
font-size: 1.2em;
padding: 3px;
text-align: center;
transition: 0.3s;
&:hover {
background-color: var(--lines);
}
}
}
}
#FloatInput {
@@ -408,20 +453,31 @@
}
}
/* Responsividade */
#statusPlayer {
text-align: center;
width: 10%;
position: fixed;
z-index: 1000;
top: 3dvh;
right: 3dvh;
padding: 0.5dvw;
border-radius: 10vw;
background-color: red;
}
@media only screen and (max-width: 1080px) {
#playerDATA {
flex-direction: column;
align-items: center;
height: auto;
#hero {
width: 40dvw;
height: 40dvw;
width: 40vw;
height: auto;
aspect-ratio: 1 / 1;
}
ul li {
font-size: 1em;
font-size: clamp(1em, 2vw, 1.2em);
}
}
@@ -433,51 +489,112 @@
#inv,
#powers {
width: 100%;
min-height: 43vh;
hgroup input[type="text"] {
width: 20dvw;
}
hgroup input[type="number"] {
width: 8dvw;
}
min-height: 60vh;
}
#status li {
border-top-right-radius: 2dvh;
border-bottom-right-radius: 2dvh;
#powers ul {
height: 30vh;
}
#powers hgroup textarea {
height: 12vh;
}
#status ul {
justify-content: center;
align-items: center;
}
#dados #list {
height: 30dvh;
height: 30vh;
}
}
#inv ul {
max-height: 43vh;
li {
min-width: calc(100% / 4);
max-width: calc(100% / 4);
min-height: calc(100% / 4);
mix-height: calc(100% / 4);
#inv {
hgroup {
input[type="text"] {
width: 25%;
}
input[type="number"] {
width: 10%;
}
}
ul {
max-height: 40vh;
li {
width: 23%;
height: 20vh;
}
}
}
}
#FloatInput {
width: 30%;
transform: translateY(50px) translateX(-50px);
width: 60%;
left: 20%;
transform: translateY(30px);
}
#box_2 {
#text_lore {
a {
height: 200dvw;
}
textarea {
height: 200dvw;
}
#box_2 #text_lore {
textarea {
height: 40vh;
}
}
#statusPlayer {
width: 35%;
padding: 2dvw;
}
}
@media screen and (max-width: 1080px) and (orientation: landscape) {
#box_1 {
flex-direction: row;
flex-wrap: wrap;
}
#dados,
#status,
#inv,
#powers {
width: 48%;
min-height: 50vh;
max-height: none;
}
#powers {
width: 100%;
margin-top: 2vh;
ul {
height: 25vh;
}
hgroup textarea {
height: 15vh;
}
}
#playerDATA #hero {
width: 40vh;
height: 40vh;
}
#FloatInput {
width: 30%;
transform: translateX(-20%) translateY(10px);
}
#inv ul li {
width: calc(100% / 6 - 4px);
height: 15vh;
}
#box_2 #text_lore textarea {
height: 30vh;
}
#statusPlayer {
width: 25%;
padding: 1dvw;
}
}

View File

@@ -2,7 +2,10 @@
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<title>ficha</title>
<link rel="stylesheet" href="css/base.css" />
<link rel="stylesheet" href="css/style.css" />
@@ -44,6 +47,9 @@
<span class="material-symbols-outlined"> edit </span>
edit
</a>
<a id="btn" class="share">
<span class="material-symbols-outlined">share</span>
</a>
</li>
<li>
<label>level:</label>
@@ -335,15 +341,29 @@
<h1>Inventario</h1>
<ul></ul>
<hgroup>
<input type="text" placeholder="item name" />
<input
type="text"
placeholder="item name"
name="item_name"
/>
<select name="durabilite">
<option>duravel?</option>
<option value="True">true</option>
<option value="False">false</option>
</select>
<input type="number" placeholder="peso" max="100" />
<input type="number" placeholder="quantidade" max="100" />
<a id="btn">add</a>
<input
type="number"
name="peso"
placeholder="peso"
max="100"
/>
<input
type="number"
name="quantidade"
placeholder="quantidade"
max="100"
/>
<a id="btn" class="inv_add">add</a>
<label>
<p id="invPA">0</p>
/
@@ -357,10 +377,23 @@
</hgroup>
</div>
<div id="powers">
<h1>Poderes</h1>
<h1>Habilidades</h1>
<ul>
<li><a>bla bla bla bla</a></li>
</ul>
<hgroup>
<input
type="text"
placeholder="nome da habilidade"
name="habilidade"
id="habl"
/>
<textarea
id="desc"
placeholder="escrava como sua habilidade ou poder funciona"
></textarea>
<a id="btn">add</a>
</hgroup>
</div>
</div>
<div id="box_2">
@@ -384,7 +417,7 @@
</ul>
</div>
</div>
<label id="statusPlayer"></label>
<!-- scripts -->
<script type="text/javascript" src="javascript/script.js"></script>
<script type="text/javascript" src="javascript/load_ficha.js"></script>

View File

@@ -1,114 +1,32 @@
let img;
let update;
let playerID;
function useInv(id, type) {
$.ajax({
url: window.api + `player/inv/${type}/${id}`,
type: "GET",
xhrFields: { withCredentials: true },
success: function (resp) {
msg(resp.Status, resp.Message);
},
error: function (resp) {
msg(
resp.responseJSON?.Status || "Erro",
resp.responseJSON?.Message || "Algo deu errado.",
);
},
});
}
function useItem(id) {
alert(id);
}
function load_ficha() {
$.ajax({
url: window.api + "player",
type: "GET",
xhrFields: { withCredentials: true },
success: function (resp) {
if (img === undefined) {
img = resp.Foto;
$("#hero").attr("src", `data:image/*;base64,${resp.Foto}`);
}
$("#vdp").text(resp.Vida);
$("#nmp").text(resp.PlayerName);
$("#lvp").text(resp.Level);
$("#idp").text(resp.Idade);
$("#alp").text(resp.Altura);
$("#conhecimento").text(resp.Conhecimento);
$("#força").text(resp.Força);
$("#destresa").text(resp.Destresa);
$("#constitution").text(resp.Constituição);
$("#inteligencia").text(resp.Inteligencia);
$("#cárisma").text(resp.Cárisma);
$("#mip").text(resp.Inventario);
$("#lore").text(resp.Descrição);
if ($("#lore_edit").attr("placeholder") !== resp.Descrição) {
$("#lore_edit").attr("placeholder", resp.Descrição);
$("#lore_edit").val(resp.Descrição);
}
},
error: function () {
window.location.href = "login.html";
},
});
}
function roll_load() {
$.ajax({
url: window.api + "roll",
type: "GET",
xhrFields: { withCredentials: true },
success: function (resp) {
switch (update) {
case undefined:
resp.Logs.forEach(function (item) {
const $li = $("<li>");
const $label = $("<label>").text(item.log);
$li.append($label);
$("#log").append($li);
update = item.id;
});
break;
default:
resp.Logs.forEach(function (item) {
if (item.id > update) {
const $li = $("<li>");
const $label = $("<label>").text(item.log);
$li.append($label);
$("#log").append($li);
update = item.id;
}
});
break;
}
$("#log").scrollTop($("#log")[0].scrollHeight);
},
});
}
function roll(d) {
$.ajax({
url: window.api + "roll",
type: "POST",
data: { roll: d },
xhrFields: { withCredentials: true },
success: function (resp) {
msg(resp.Status, resp.Message);
},
});
async function useInv(id, type) {
try {
const resp = await $.ajax({
url: `${window.api}player/inv/${type}/${id}`,
type: "GET",
xhrFields: { withCredentials: true },
});
msg(resp.Status, resp.Message);
} catch (err) {
msg(
err.responseJSON?.Status || "Erro",
err.responseJSON?.Message || "Algo deu errado.",
);
}
}
function invPlayer() {
$.ajax({
url: window.api + "player/inv",
url: `${window.api}player/inv`,
type: "GET",
xhrFields: { withCredentials: true },
success: function (resp) {
const buildItem = function (item) {
success(resp) {
const $invList = $("#inv ul").empty();
resp.InvItems.forEach((item) => {
const $li = $("<li>");
$li.append($("<label>").text(item.itemname));
$li.append($("<label>").text(`tem: ${item.itemquantidade}`));
@@ -127,34 +45,143 @@ function invPlayer() {
});
$li.append($delBtn);
return $li;
};
$("#inv ul").empty();
resp.InvItems.forEach((item) => {
$("#inv ul").append(buildItem(item));
$invList.append($li);
});
$("#invPA").text(resp.invPeso);
},
error: function () {
error() {
$("#inv ul").empty();
$("#invPA").text(0);
},
});
}
load_ficha();
function invAdd() {
const nome = $("input[name='item_name']").val();
const durabilidade = $("select[name='durabilite']").val();
const peso = $("input[name='peso']").val();
const quantidade = $("input[name='quantidade']").val();
$.ajax({
url: `${window.api}player/inv`,
type: "POST",
data: { item_name: nome, durabilite: durabilidade, peso, quantidade },
xhrFields: { withCredentials: true },
success(resp) {
msg(resp.Status, resp.Message);
$("input, select").val("");
$("select[name='durabilite']").val("duravel?");
},
error(resp) {
msg(
resp.responseJSON?.Status || "Erro",
resp.responseJSON?.Message || "Algo deu errado.",
);
},
});
}
function loadFicha() {
$.ajax({
url: `${window.api}player`,
type: "GET",
xhrFields: { withCredentials: true },
success(resp) {
if (!img) {
img = resp.Foto;
$("#hero").attr("src", `data:image/*;base64,${resp.Foto}`);
}
if (!playerID) playerID = resp.PlayerID;
$("#vdp").text(resp.Vida);
$("#nmp").text(resp.PlayerName);
$("#lvp").text(resp.Level);
$("#idp").text(resp.Idade);
$("#alp").text(resp.Altura);
$("#conhecimento").text(resp.Conhecimento);
$("#força").text(resp.Força);
$("#destresa").text(resp.Destresa);
$("#constitution").text(resp.Constituição);
$("#inteligencia").text(resp.Inteligencia);
$("#cárisma").text(resp.Cárisma);
$("#mip").text(resp.Inventario);
$("#lore").text(resp.Descrição);
if ($("#lore_edit").attr("placeholder") !== resp.Descrição) {
$("#lore_edit").attr("placeholder", resp.Descrição);
$("#lore_edit").val(resp.Descrição);
}
const statusMap = [
{ limit: 0, text: "Status: morto(a)" },
{ limit: 5, text: "Status: morrendo" },
{ limit: 50, text: "Status: muito ferido(a)" },
{ limit: 70, text: "Status: ferido(a)" },
{ limit: 100, text: "Status: normal" },
];
const status = statusMap.find((s) => resp.VidaPorcentagem <= s.limit);
$("#statusPlayer").text(status?.text || "Status: desconhecido");
},
error() {
window.location.href = "login.html";
},
});
}
function rollLoad() {
$.ajax({
url: `${window.api}roll`,
type: "GET",
xhrFields: { withCredentials: true },
success(resp) {
let latestId = update || 0;
resp.Logs.forEach((item) => {
if (item.id > (update || 0)) {
const $li = $("<li>");
$li.append($("<label>").text(item.log));
$("#log").append($li);
if (item.id > latestId) latestId = item.id;
}
});
update = latestId;
$("#log").scrollTop($("#log")[0].scrollHeight);
},
});
}
function roll(dado) {
$.ajax({
url: `${window.api}roll`,
type: "POST",
data: { roll: dado },
xhrFields: { withCredentials: true },
success(resp) {
msg(resp.Status, resp.Message);
},
error(resp) {
msg(
resp.responseJSON?.Status || "Erro",
resp.responseJSON?.Message || "Falha ao rolar dados.",
);
},
});
}
$(document).ready(function () {
$(".updown").click(function () {
const atb = $(this).data("atb");
const updown = $(this).data("updown");
const dir = $(this).data("updown");
$.ajax({
url: `${window.api}player/${atb}/${updown}`,
url: `${window.api}player/${atb}/${dir}`,
type: "PATCH",
xhrFields: { withCredentials: true },
error: function (resp) {
error(resp) {
msg(
resp.responseJSON?.Status || "Erro",
resp.responseJSON?.Message || "Algo deu errado.",
@@ -163,9 +190,13 @@ $(document).ready(function () {
});
});
setInterval(function () {
load_ficha();
roll_load();
$(".inv_add").click(invAdd);
setInterval(() => {
loadFicha();
rollLoad();
invPlayer();
}, 1000);
loadFicha();
});

View File

@@ -2,7 +2,10 @@
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<title>login</title>
<link rel="stylesheet" href="css/base.css" />
<link rel="stylesheet" href="css/login.css" />

View File

@@ -2,7 +2,10 @@
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<title>registrar</title>
<link rel="stylesheet" href="css/base.css" />
<link rel="stylesheet" href="css/register.css" />