diff --git a/src/app.vue b/src/app.vue
index c23fdf46..b47e296a 100644
--- a/src/app.vue
+++ b/src/app.vue
@@ -294,8 +294,28 @@ function update_all(
hat,
cloak,
pet,
+
+ available_points,
+ vitality,
+ strength,
+ chance,
+ intelligence,
+ wisdom,
+ agility,
} = character;
+ // @ts-ignore
+ if (selected_character.value.available_points !== available_points ||
+ selected_character.value.vitality !== vitality ||
+ selected_character.value.strength !== strength ||
+ selected_character.value.chance !== chance ||
+ selected_character.value.intelligence !== intelligence ||
+ selected_character.value.wisdom !== wisdom ||
+ selected_character.value.agility !== agility
+ ) {
+ selected_character.value = current_character(state);
+ }
+
let equipment_changed = false;
// @ts-ignore
diff --git a/src/assets/translations/en.yaml b/src/assets/translations/en.yaml
index c0552205..2f8b19cb 100644
--- a/src/assets/translations/en.yaml
+++ b/src/assets/translations/en.yaml
@@ -215,6 +215,15 @@ APP_CHARACTER_CREATE_OK: Character created!
APP_CHARACTER_CREATE_ERROR: Error while creating character
APP_CHARACTER_NO_CHARACTERS: You must lock a character to play
+APP_CHARACTER_STAT_LIFE_POINT: Life Points
+APP_CHARACTER_STAT_PA: Action Points
+APP_CHARACTER_STAT_PM: Movement Points
+APP_CHARACTER_STAT_EXP: Experience
+APP_CHARACTER_STAT_ENERGY: Energy
+APP_CHARACTER_STAT_LEVEL: Level
+APP_CHARACTER_STAT_CHARACTERISTICS: Characteristics
+APP_CHARACTER_STAT_CAPITAL: Capital
+
APP_GAME_CHAT_COPY_ADDRESS: Copy address
APP_GAME_CHAT_COPIED: Address copied to clipboard
APP_GAME_CHAT_NO_CHARACTER: You must select a character first
diff --git a/src/assets/translations/fr.yaml b/src/assets/translations/fr.yaml
index 0c07055d..6dff2ea5 100644
--- a/src/assets/translations/fr.yaml
+++ b/src/assets/translations/fr.yaml
@@ -216,6 +216,15 @@ APP_CHARACTER_CREATE_OK: Personnage créé !
APP_CHARACTER_CREATE_ERROR: Erreur lors de la création du personnage
APP_CHARACTER_NO_CHARACTERS: Vous devez verrouiller un personnage pour jouer
+APP_CHARACTER_STAT_LIFE_POINT: Points de vie
+APP_CHARACTER_STAT_PA: Points d'actions
+APP_CHARACTER_STAT_PM: Points de mouvements
+APP_CHARACTER_STAT_EXP: Experience
+APP_CHARACTER_STAT_ENERGY: Energie
+APP_CHARACTER_STAT_LEVEL: Niveau
+APP_CHARACTER_STAT_CHARACTERISTICS: Caractéristiques
+APP_CHARACTER_STAT_CAPITAL: Capital
+
APP_GAME_CHAT_COPY_ADDRESS: Copier l'adresse
APP_GAME_CHAT_COPIED: Adresse copiée dans le presse-papiers
APP_GAME_CHAT_NO_CHARACTER: Vous devez d'abord sélectionner un personnage
diff --git a/src/assets/translations/jp.yaml b/src/assets/translations/jp.yaml
index f5c3479b..2924e72d 100644
--- a/src/assets/translations/jp.yaml
+++ b/src/assets/translations/jp.yaml
@@ -215,6 +215,15 @@ APP_CHARACTER_CREATE_OK: キャラクターが作成されました!
APP_CHARACTER_CREATE_ERROR: キャラクターの作成中にエラーが発生しました
APP_CHARACTER_NO_CHARACTERS: プレイするにはキャラクターをロックする必要があります
+APP_CHARACTER_STAT_LIFE_POINT: ライフポイント
+APP_CHARACTER_STAT_PA: アクションポイント
+APP_CHARACTER_STAT_PM: ムーブポイント
+APP_CHARACTER_STAT_EXP: 経験値
+APP_CHARACTER_STAT_ENERGY: エネルギー
+APP_CHARACTER_STAT_LEVEL: レベル
+APP_CHARACTER_STAT_CHARACTERISTICS: 特性
+APP_CHARACTER_STAT_CAPITAL: キャピタル
+
APP_GAME_CHAT_COPY_ADDRESS: アドレスをコピー
APP_GAME_CHAT_COPIED: アドレスがクリップボードにコピーされました
APP_GAME_CHAT_NO_CHARACTER: まずキャラクターを選択する必要があります
diff --git a/src/components/cards/equipment-slot.vue b/src/components/cards/equipment-slot.vue
index 23e4ac13..b793a5b2 100644
--- a/src/components/cards/equipment-slot.vue
+++ b/src/components/cards/equipment-slot.vue
@@ -144,12 +144,17 @@ img.slot-img
padding .5em
filter grayscale(1)
opacity .3
+ position absolute;
+ z-index 1;
img.equipped-img
width 100%
height 100%
object-fit contain
cursor pointer
+ position absolute;
+ z-index 1;
+ padding 2px
.slot
pointer-events none
@@ -158,8 +163,9 @@ img.equipped-img
height 100%
top 0
left 0
- box-shadow: inset 0 0 15px 0 #212121
- border 1px solid #212121
+ box-shadow: inset 0 0 5px 0 #212121db
+ border 2px solid #ddd8c9
+ background #8d8980;
&.highlighted
box-shadow: inset 0 0 15px 0 #F9A825
border 1px solid #F9A825
diff --git a/src/components/cards/item-description.vue b/src/components/cards/item-description.vue
index c327ae5e..3ab4caef 100644
--- a/src/components/cards/item-description.vue
+++ b/src/components/cards/item-description.vue
@@ -121,6 +121,7 @@ const stats = computed(() => {
overflow hidden
position relative
height 250px
+ color #514a3c
.header
display flex
flex-flow row nowrap
@@ -171,6 +172,7 @@ const stats = computed(() => {
text-transform uppercase
font-size .9em
.right-content
+ color white
overflow hidden
overflow-y scroll
height calc(100% - .5em)
diff --git a/src/components/cards/item-equipments.vue b/src/components/cards/item-equipments.vue
index ecb78173..e11e5724 100644
--- a/src/components/cards/item-equipments.vue
+++ b/src/components/cards/item-equipments.vue
@@ -223,8 +223,8 @@ const is_dragging_pet = computed(() => {
.item-equipments
position relative
grid-area perso
- border 5px double #212121
- background linear-gradient(to bottom, #212121, rgba(#455A64, .7) 50%)
+ border 3px solid #ffffff;
+ background #514a3ccc
border-radius 12px
display flex
flex-flow row nowrap
@@ -262,34 +262,34 @@ const is_dragging_pet = computed(() => {
position relative
.title
grid-area title
- width 80px
+ width 74px
height @width
margin-right 1em
.amulet
grid-area amulet
.weapon
grid-area weapon
- width 80px
+ width 74px
height @width
margin-left 1em
.left_ring
grid-area left_ring
.belt
grid-area belt
- width 80px
+ width 74px
height @width
margin-top 1em
.right_ring
grid-area right_ring
.boots
grid-area boots
- width 80px
+ width 74px
height @width
.right
display flex
flex-flow column nowrap
>*
- width 80px
+ width 74px
height @width
margin-bottom 5px
position relative
diff --git a/src/components/cards/item-inventory.vue b/src/components/cards/item-inventory.vue
index 0bd31a5e..5567eac7 100644
--- a/src/components/cards/item-inventory.vue
+++ b/src/components/cards/item-inventory.vue
@@ -338,6 +338,8 @@ const items = computed(() => {
overflow hidden
overflow-y auto
padding .5em
+ background #beb998cc
+ border-radius 0 0 9px 9px
.item
position relative
cursor pointer
diff --git a/src/components/game-ui/game-characteristic.vue b/src/components/game-ui/game-characteristic.vue
new file mode 100644
index 00000000..5f110442
--- /dev/null
+++ b/src/components/game-ui/game-characteristic.vue
@@ -0,0 +1,349 @@
+
+.game-stats
+ .stats
+ .header
+ // @todo use image_url
+ img(:src="`https://assets.aresrpg.world/classe/${selected_character.classe}_${selected_character.sex}.jpg`")
+ span.name {{ selected_character.name }}
+ .container
+ .level {{ t('APP_CHARACTER_STAT_LEVEL') }} 1
+ .energy.darkline
+ .label {{ t('APP_CHARACTER_STAT_ENERGY') }}
+ .progress
+ div.progress-bar(:style="{ width: (selected_character.soul / 100) * 100 + '%' }")
+ .experience
+ .label {{ t('APP_CHARACTER_STAT_EXP') }}
+ .progress
+ // @todo calculate experience
+ div.progress-bar(:style="{ width: '0%' }")
+ .line.life.darkline
+ .label
+ img(src="../../assets/statistics/health.png")
+ span {{ t('APP_CHARACTER_STAT_LIFE_POINT') }}
+ div {{ selected_character.health }} / {{ supposed_max_health }}
+ .line.PA
+ .label
+ img(src="../../assets/statistics/action.png")
+ span {{ t('APP_CHARACTER_STAT_PA') }}
+ div {{ pa }}
+ .line.PM.darkline
+ .label
+ img(src="../../assets/statistics/movement.png")
+ span {{ t('APP_CHARACTER_STAT_PM') }}
+ div {{ pm }}
+ .section {{ t('APP_CHARACTER_STAT_CHARACTERISTICS') }}
+ .line.characteristic(
+ v-for="(stat, key, index) in stats"
+ :key="key"
+ :class="{ darkline: index % 2 === 0 }"
+ )
+ .label
+ img(:src="stat.imagePath")
+ span {{ stat.label }}
+ .leftStats
+ div {{ calculate_stat_value(key) }}
+ .upgrade(
+ v-if="can_upgrade()"
+ @click="() => add_pending_allocated_stat(key, 1)"
+ )
+ .section.light
+ div {{ t('APP_CHARACTER_STAT_CAPITAL') }}
+ span {{ selected_character.available_points - get_pending_allocated_stats_count() }}
+ //- .btn(v-if="has_pending_allocated_stats()" @click="cancel_pending_allocated_stats")
+ //- RadixIconsCross2
+ //- span Annuler
+ //- .btn(v-if="has_pending_allocated_stats()" @click="validate_stats")
+ //- FluentCheckmark12Regular
+ //- span Valider
+ .right
+ vs-button.cancel(icon color="#E74C3C" v-if="has_pending_allocated_stats()" @click="cancel_pending_allocated_stats")
+ RadixIconsCross2
+ vs-button.accept(icon color="#2ECC71" v-if="has_pending_allocated_stats()" @click="validate_stats")
+ FluentCheckmark12Regular
+
+
+
+
+
diff --git a/src/components/game-ui/game-interface.vue b/src/components/game-ui/game-interface.vue
index 0146fa90..bc42c7dc 100644
--- a/src/components/game-ui/game-interface.vue
+++ b/src/components/game-ui/game-interface.vue
@@ -6,6 +6,7 @@
characterSelectVue
.middle
gameInventory(v-if="inventory_opened")
+ gameCharacteristic(v-if="stats_opened")
.bottom_panel
gameChat
gameHealth(
@@ -25,6 +26,7 @@ import gameChat from './game-chat.vue';
import gameHealth from './game-health.vue';
import gameSpellbar from './game-spellbar.vue';
import gameInventory from './game-inventory.vue';
+import gameCharacteristic from './game-characteristic.vue';
const stats_opened = ref(false);
const spells_opened = ref(false);
diff --git a/src/components/game-ui/game-inventory.vue b/src/components/game-ui/game-inventory.vue
index 6d5adb3f..f6c387f8 100644
--- a/src/components/game-ui/game-inventory.vue
+++ b/src/components/game-ui/game-inventory.vue
@@ -65,10 +65,6 @@ watch(owned_items, items => {
height 50px
.i-inv
- border 1px solid rgba(#eee, .3)
- border-radius 12px
- border-top-right-radius 0
- border-bottom-right-radius 0
height 100%
.game-inventory
@@ -78,38 +74,43 @@ watch(owned_items, items => {
height 100%
width 80%
max-width 900px
+ max-height 770px
+ overflow-y auto
+ padding-right 10px
+
.item
grid-area item
- border 5px double #212121
- background linear-gradient(to bottom, #212121, rgba(#455A64, .7) 50%)
+ border 3px solid #ffffff
+ background #beb998cc
border-radius 12px
padding .5em
font-size .9rem
.inventory
grid-area inventory
- border 5px double #212121
+ border 3px solid #ffffff
border-radius 12px
- padding .25em
- padding-top .5em
- background linear-gradient(to bottom, #212121, rgba(#455A64, .3) 50%)
display flex
flex-flow column nowrap
justify-content stretch
.header
display flex
justify-content center
- margin-bottom 20px
+ padding-top .5em
+ padding-bottom 10px
+ background #514a3ccc
+ border-radius 9px 9px 0px 0px
img
- width 50px
+ width 34px
+ border-radius 6px
margin 0 5px 0 0
height @width
padding .25em
cursor pointer
+ background-color #ff6100cc
&.selected
- filter drop-shadow(1px 2px 3px #FFF59D)
+ background-color #514a3ccc
+ border solid 2px #cccccc
.content
- border 1px solid rgba(#eee, .3)
- // background rgba(#000, .3)
border-radius 12px
border-top-right-radius 0
border-bottom-right-radius 0
diff --git a/src/core/sui/client.js b/src/core/sui/client.js
index a42cefdd..27910d1d 100644
--- a/src/core/sui/client.js
+++ b/src/core/sui/client.js
@@ -1313,3 +1313,37 @@ replace_rule('royaltyRulePackageId', {
})
},
})
+
+export async function sui_add_stats({ character, stats }) {
+ const tx = new Transaction()
+
+ sdk.add_header(tx)
+
+ const { kiosks, finalize } = await sdk.get_user_kiosks({
+ tx,
+ address: get_address(),
+ })
+
+ const kiosk_cap_ref = new Map()
+
+ function get_kiosk_cap_ref(kiosk_id) {
+ if (!kiosk_cap_ref.has(kiosk_id)) {
+ kiosk_cap_ref.set(kiosk_id, kiosks.get(kiosk_id)())
+ }
+ return kiosk_cap_ref.get(kiosk_id)
+ }
+ const kiosk_cap = get_kiosk_cap_ref(character.kiosk_id)
+
+ Object.entries(stats).forEach(([stat, amount]) =>
+ sdk.add_stats({
+ tx,
+ kiosk: character.kiosk_id,
+ kiosk_cap,
+ character_id: character.id,
+ stat,
+ amount,
+ }),
+ )
+
+ await execute(tx)
+}