feat: implement initial in-game store system with web-based UI.
This commit is contained in:
parent
56f0f1c971
commit
58902f0c29
@ -4,7 +4,7 @@
|
||||
* File: fnc_handleUIEvents.sqf
|
||||
* Author: IDSolutions
|
||||
* Date: 2026-01-28
|
||||
* Last Update: 2026-02-04
|
||||
* Last Update: 2026-02-06
|
||||
* Public: No
|
||||
*
|
||||
* Description:
|
||||
@ -41,7 +41,7 @@ switch (_event) do {
|
||||
case "actor::open::vlocker": { [FORGE_Locker_Box, player, false] spawn AFUNC(arsenal,openBox) };
|
||||
case "actor::open::phone": { hint "Phone interaction is not yet implemented."; };
|
||||
case "actor::open::iplayer": { hint "Player interaction is not yet implemented." };
|
||||
case "actor::open::store": { hint "Store interaction is not yet implemented."; };
|
||||
case "actor::open::store": { [] spawn EFUNC(store,openUI); };
|
||||
default { hint format ["Unhandled UI event: %1", _event]; };
|
||||
};
|
||||
|
||||
|
||||
@ -75,6 +75,13 @@ const baseMenuItems = [
|
||||
icon: "",
|
||||
action: "actor::open::org",
|
||||
},
|
||||
{
|
||||
id: "store",
|
||||
title: "Store",
|
||||
description: "Browse and purchase items from the store",
|
||||
icon: "",
|
||||
action: "actor::open::store",
|
||||
},
|
||||
];
|
||||
|
||||
const actionDefinitions = {
|
||||
|
||||
1
arma/client/addons/store/$PBOPREFIX$
Normal file
1
arma/client/addons/store/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
||||
forge\forge_client\addons\store
|
||||
19
arma/client/addons/store/CfgEventHandlers.hpp
Normal file
19
arma/client/addons/store/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
class Extended_PreStart_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_PreInit_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
|
||||
clientInit = QUOTE(call COMPILE_SCRIPT(XEH_preInitClient));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_PostInit_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_SCRIPT(XEH_postInit));
|
||||
clientInit = QUOTE(call COMPILE_SCRIPT(XEH_postInitClient));
|
||||
};
|
||||
};
|
||||
4
arma/client/addons/store/README.md
Normal file
4
arma/client/addons/store/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
forge_client_store
|
||||
===================
|
||||
|
||||
Description for this addon
|
||||
3
arma/client/addons/store/XEH_PREP.hpp
Normal file
3
arma/client/addons/store/XEH_PREP.hpp
Normal file
@ -0,0 +1,3 @@
|
||||
PREP(handleUIEvents);
|
||||
PREP(initStoreClass);
|
||||
PREP(openUI);
|
||||
1
arma/client/addons/store/XEH_postInit.sqf
Normal file
1
arma/client/addons/store/XEH_postInit.sqf
Normal file
@ -0,0 +1 @@
|
||||
#include "script_component.hpp"
|
||||
3
arma/client/addons/store/XEH_postInitClient.sqf
Normal file
3
arma/client/addons/store/XEH_postInitClient.sqf
Normal file
@ -0,0 +1,3 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
call FUNC(initStoreClass);
|
||||
10
arma/client/addons/store/XEH_preInit.sqf
Normal file
10
arma/client/addons/store/XEH_preInit.sqf
Normal file
@ -0,0 +1,10 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
PREP_RECOMPILE_START;
|
||||
#include "XEH_PREP.hpp"
|
||||
PREP_RECOMPILE_END;
|
||||
|
||||
// private _category = [QUOTE(MOD_NAME), LLSTRING(displayName)];
|
||||
|
||||
// #include "initSettings.inc.sqf"
|
||||
// #include "initKeybinds.inc.sqf"
|
||||
1
arma/client/addons/store/XEH_preInitClient.sqf
Normal file
1
arma/client/addons/store/XEH_preInitClient.sqf
Normal file
@ -0,0 +1 @@
|
||||
#include "script_component.hpp"
|
||||
2
arma/client/addons/store/XEH_preStart.sqf
Normal file
2
arma/client/addons/store/XEH_preStart.sqf
Normal file
@ -0,0 +1,2 @@
|
||||
#include "script_component.hpp"
|
||||
#include "XEH_PREP.hpp"
|
||||
21
arma/client/addons/store/config.cpp
Normal file
21
arma/client/addons/store/config.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
author = AUTHOR;
|
||||
authors[] = {"J.Schmidt"};
|
||||
url = ECSTRING(main,url);
|
||||
name = COMPONENT_NAME;
|
||||
requiredVersion = REQUIRED_VERSION;
|
||||
requiredAddons[] = {
|
||||
"forge_client_main"
|
||||
};
|
||||
units[] = {};
|
||||
weapons[] = {};
|
||||
VERSION_CONFIG;
|
||||
};
|
||||
};
|
||||
|
||||
#include "CfgEventHandlers.hpp"
|
||||
#include "ui\RscCommon.hpp"
|
||||
#include "ui\RscStore.hpp"
|
||||
38
arma/client/addons/store/functions/fnc_handleUIEvents.sqf
Normal file
38
arma/client/addons/store/functions/fnc_handleUIEvents.sqf
Normal file
@ -0,0 +1,38 @@
|
||||
#include "..\script_component.hpp"
|
||||
|
||||
/*
|
||||
* File: fnc_handleUIEvents.sqf
|
||||
* Author: IDSolutions
|
||||
* Date: 2026-01-28
|
||||
* Last Update: 2026-02-06
|
||||
* Public: No
|
||||
*
|
||||
* Description:
|
||||
* Handles the UI events.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: [CONTROL] - The control that triggered the event
|
||||
* 1: [BOOL] - Whether the event is from a confirm dialog
|
||||
* 2: [STRING] - The message containing the event data
|
||||
*
|
||||
* Return Value:
|
||||
* UI events handled [BOOL]
|
||||
*
|
||||
* Example:
|
||||
* call forge_client_store_fnc_handleUIEvents;
|
||||
*/
|
||||
|
||||
params ["_control", "_isConfirmDialog", "_message"];
|
||||
|
||||
private _alert = fromJSON _message;
|
||||
private _event = _alert get "event";
|
||||
private _data = _alert get "data";
|
||||
|
||||
diag_log format ["[FORGE:Client:Store] Handling UI event: %1 with data: %2", _event, _data];
|
||||
|
||||
switch (_event) do {
|
||||
case "store::close": { closeDialog 1; };
|
||||
default { hint format ["Unhandled UI event: %1", _event]; };
|
||||
};
|
||||
|
||||
true;
|
||||
38
arma/client/addons/store/functions/fnc_initStoreClass.sqf
Normal file
38
arma/client/addons/store/functions/fnc_initStoreClass.sqf
Normal file
@ -0,0 +1,38 @@
|
||||
#include "..\script_component.hpp"
|
||||
|
||||
/*
|
||||
* File: fnc_initStoreClass.sqf
|
||||
* Author: IDSolutions
|
||||
* Date: 2026-01-28
|
||||
* Last Update: 2026-02-06
|
||||
* Public: Yes
|
||||
*
|
||||
* Description:
|
||||
* Initializes the store class for managing store data.
|
||||
* Provides methods for loading and applying store data.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* Store class object [HASHMAP OBJECT]
|
||||
*
|
||||
* Example:
|
||||
* call forge_client_store_fnc_initStoreClass
|
||||
*/
|
||||
|
||||
#pragma hemtt ignore_variables ["_self"]
|
||||
GVAR(StoreClass) = createHashMapObject [[
|
||||
["#type", "IStoreClass"],
|
||||
["#create", {
|
||||
_self set ["uid", getPlayerUID player];
|
||||
_self set ["store", createHashMap];
|
||||
_self set ["isLoaded", false];
|
||||
_self set ["lastSave", time];
|
||||
|
||||
systemChat format ["Store class initialized for %1", (name player)];
|
||||
diag_log "[FORGE:Client:Store] Store Class Initialized!";
|
||||
}]
|
||||
]];
|
||||
|
||||
GVAR(StoreClass)
|
||||
35
arma/client/addons/store/functions/fnc_openUI.sqf
Normal file
35
arma/client/addons/store/functions/fnc_openUI.sqf
Normal file
@ -0,0 +1,35 @@
|
||||
#include "..\script_component.hpp"
|
||||
|
||||
/*
|
||||
* File: fnc_openUI.sqf
|
||||
* Author: IDSolutions
|
||||
* Date: 2026-01-28
|
||||
* Last Update: 2026-02-06
|
||||
* Public: No
|
||||
*
|
||||
* Description:
|
||||
* Opens the store interface.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* UI opened [BOOL]
|
||||
*
|
||||
* Example:
|
||||
* call forge_client_store_fnc_openUI;
|
||||
*/
|
||||
|
||||
private _display = createDialog ["RscStore", true];
|
||||
private _ctrl = _display displayCtrl 1004;
|
||||
|
||||
_ctrl ctrlAddEventHandler ["JSDialog", {
|
||||
params ["_control", "_isConfirmDialog", "_message"];
|
||||
|
||||
[_control, _isConfirmDialog, _message] call FUNC(handleUIEvents);
|
||||
}];
|
||||
|
||||
_ctrl ctrlWebBrowserAction ["LoadFile", QPATHTOF2(ui\_site\index.html)];
|
||||
// _ctrl ctrlWebBrowserAction ["OpenDevConsole"];
|
||||
|
||||
true;
|
||||
1
arma/client/addons/store/initKeybinds.inc.sqf
Normal file
1
arma/client/addons/store/initKeybinds.inc.sqf
Normal file
@ -0,0 +1 @@
|
||||
|
||||
1
arma/client/addons/store/initSettings.inc.sqf
Normal file
1
arma/client/addons/store/initSettings.inc.sqf
Normal file
@ -0,0 +1 @@
|
||||
|
||||
9
arma/client/addons/store/script_component.hpp
Normal file
9
arma/client/addons/store/script_component.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
#define COMPONENT store
|
||||
#define COMPONENT_BEAUTIFIED Store
|
||||
#include "\forge\forge_client\addons\main\script_mod.hpp"
|
||||
|
||||
// #define DEBUG_MODE_FULL
|
||||
// #define DISABLE_COMPILE_CACHE
|
||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||
|
||||
#include "\forge\forge_client\addons\main\script_macros.hpp"
|
||||
8
arma/client/addons/store/stringtable.xml
Normal file
8
arma/client/addons/store/stringtable.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project name="FFE">
|
||||
<Package name="Store">
|
||||
<Key ID="STR_forge_client_store_displayName">
|
||||
<English>Store</English>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
||||
98
arma/client/addons/store/ui/RscCommon.hpp
Normal file
98
arma/client/addons/store/ui/RscCommon.hpp
Normal file
@ -0,0 +1,98 @@
|
||||
// Control types
|
||||
#define CT_STATIC 0
|
||||
#define CT_BUTTON 1
|
||||
#define CT_EDIT 2
|
||||
#define CT_SLIDER 3
|
||||
#define CT_COMBO 4
|
||||
#define CT_LISTBOX 5
|
||||
#define CT_TOOLBOX 6
|
||||
#define CT_CHECKBOXES 7
|
||||
#define CT_PROGRESS 8
|
||||
#define CT_HTML 9
|
||||
#define CT_STATIC_SKEW 10
|
||||
#define CT_ACTIVETEXT 11
|
||||
#define CT_TREE 12
|
||||
#define CT_STRUCTURED_TEXT 13
|
||||
#define CT_CONTEXT_MENU 14
|
||||
#define CT_CONTROLS_GROUP 15
|
||||
#define CT_SHORTCUTBUTTON 16
|
||||
#define CT_HITZONES 17
|
||||
#define CT_XKEYDESC 40
|
||||
#define CT_XBUTTON 41
|
||||
#define CT_XLISTBOX 42
|
||||
#define CT_XSLIDER 43
|
||||
#define CT_XCOMBO 44
|
||||
#define CT_ANIMATED_TEXTURE 45
|
||||
#define CT_OBJECT 80
|
||||
#define CT_OBJECT_ZOOM 81
|
||||
#define CT_OBJECT_CONTAINER 82
|
||||
#define CT_OBJECT_CONT_ANIM 83
|
||||
#define CT_LINEBREAK 98
|
||||
#define CT_USER 99
|
||||
#define CT_MAP 100
|
||||
#define CT_MAP_MAIN 101
|
||||
#define CT_LISTNBOX 102
|
||||
#define CT_ITEMSLOT 103
|
||||
#define CT_CHECKBOX 77
|
||||
|
||||
// Static styles
|
||||
#define ST_POS 0x0F
|
||||
#define ST_HPOS 0x03
|
||||
#define ST_VPOS 0x0C
|
||||
#define ST_LEFT 0x00
|
||||
#define ST_RIGHT 0x01
|
||||
#define ST_CENTER 0x02
|
||||
#define ST_DOWN 0x04
|
||||
#define ST_UP 0x08
|
||||
#define ST_VCENTER 0x0C
|
||||
|
||||
#define ST_TYPE 0xF0
|
||||
#define ST_SINGLE 0x00
|
||||
#define ST_MULTI 0x10
|
||||
#define ST_TITLE_BAR 0x20
|
||||
#define ST_PICTURE 0x30
|
||||
#define ST_FRAME 0x40
|
||||
#define ST_BACKGROUND 0x50
|
||||
#define ST_GROUP_BOX 0x60
|
||||
#define ST_GROUP_BOX2 0x70
|
||||
#define ST_HUD_BACKGROUND 0x80
|
||||
#define ST_TILE_PICTURE 0x90
|
||||
#define ST_WITH_RECT 0xA0
|
||||
#define ST_LINE 0xB0
|
||||
#define ST_UPPERCASE 0xC0
|
||||
#define ST_LOWERCASE 0xD0
|
||||
|
||||
#define ST_SHADOW 0x100
|
||||
#define ST_NO_RECT 0x200
|
||||
#define ST_KEEP_ASPECT_RATIO 0x800
|
||||
|
||||
// Slider styles
|
||||
#define SL_DIR 0x400
|
||||
#define SL_VERT 0
|
||||
#define SL_HORZ 0x400
|
||||
|
||||
#define SL_TEXTURES 0x10
|
||||
|
||||
// progress bar
|
||||
#define ST_VERTICAL 0x01
|
||||
#define ST_HORIZONTAL 0
|
||||
|
||||
// Listbox styles
|
||||
#define LB_TEXTURES 0x10
|
||||
#define LB_MULTI 0x20
|
||||
|
||||
// Tree styles
|
||||
#define TR_SHOWROOT 1
|
||||
#define TR_AUTOCOLLAPSE 2
|
||||
|
||||
// Default text sizes
|
||||
#define GUI_TEXT_SIZE_SMALL (GUI_GRID_H * 0.8)
|
||||
#define GUI_TEXT_SIZE_MEDIUM (GUI_GRID_H * 1)
|
||||
#define GUI_TEXT_SIZE_LARGE (GUI_GRID_H * 1.2)
|
||||
|
||||
// Pixel grid
|
||||
#define pixelScale 0.50
|
||||
#define GRID_W (pixelW * pixelGrid * pixelScale)
|
||||
#define GRID_H (pixelH * pixelGrid * pixelScale)
|
||||
|
||||
class RscText;
|
||||
21
arma/client/addons/store/ui/RscStore.hpp
Normal file
21
arma/client/addons/store/ui/RscStore.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
class RscStore {
|
||||
idd = 1003;
|
||||
fadeIn = 0;
|
||||
fadeOut = 0;
|
||||
duration = 1e011;
|
||||
onLoad = "uiNamespace setVariable ['RscStore', _this select 0]";
|
||||
onUnLoad = "uinamespace setVariable ['RscStore', nil]";
|
||||
|
||||
class controlsBackground {};
|
||||
class controls {
|
||||
class IFrame: RscText {
|
||||
type = 106;
|
||||
idc = 1004;
|
||||
x = "safeZoneXAbs";
|
||||
y = "safeZoneY";
|
||||
w = "safeZoneWAbs";
|
||||
h = "safeZoneH";
|
||||
colorBackground[] = {0, 0, 0, 0};
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -5,7 +5,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Store</title>
|
||||
<link rel="stylesheet" href="store.css" />
|
||||
<!-- <link rel="stylesheet" href="style.css" /> -->
|
||||
<!--
|
||||
Dynamic Resource Loading
|
||||
The following script loads CSS and JavaScript files dynamically using the A3API
|
||||
@ -14,10 +14,10 @@
|
||||
<script>
|
||||
Promise.all([
|
||||
A3API.RequestFile(
|
||||
"forge\\forge_client\\addons\\actor\\ui\\_site\\store.css",
|
||||
"forge\\forge_client\\addons\\store\\ui\\_site\\style.css",
|
||||
),
|
||||
A3API.RequestFile(
|
||||
"forge\\forge_client\\addons\\actor\\ui\\_site\\store.js",
|
||||
"forge\\forge_client\\addons\\store\\ui\\_site\\script.js",
|
||||
),
|
||||
]).then(([css, js]) => {
|
||||
const style = document.createElement("style");
|
||||
@ -48,7 +48,7 @@
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<button class="action-btn cart-btn" id="cartToggle">
|
||||
<span class="cart-icon">🛒</span>
|
||||
<span class="cart-icon">Cart</span>
|
||||
<span class="cart-count">0</span>
|
||||
</button>
|
||||
<button class="action-btn close-btn">Close</button>
|
||||
@ -65,27 +65,27 @@
|
||||
<div class="panel-content">
|
||||
<div class="category-list">
|
||||
<button class="category-item active" data-category="all">
|
||||
<span class="category-icon">📦</span>
|
||||
<span class="category-icon"></span>
|
||||
<span class="category-name">All Items</span>
|
||||
<span class="category-count">24</span>
|
||||
</button>
|
||||
<button class="category-item" data-category="weapons">
|
||||
<span class="category-icon">🔫</span>
|
||||
<span class="category-icon"></span>
|
||||
<span class="category-name">Weapons</span>
|
||||
<span class="category-count">8</span>
|
||||
</button>
|
||||
<button class="category-item" data-category="equipment">
|
||||
<span class="category-icon">🎽</span>
|
||||
<span class="category-icon"></span>
|
||||
<span class="category-name">Equipment</span>
|
||||
<span class="category-count">6</span>
|
||||
</button>
|
||||
<button class="category-item" data-category="medical">
|
||||
<span class="category-icon">💊</span>
|
||||
<span class="category-icon"></span>
|
||||
<span class="category-name">Medical</span>
|
||||
<span class="category-count">5</span>
|
||||
</button>
|
||||
<button class="category-item" data-category="supplies">
|
||||
<span class="category-icon">📦</span>
|
||||
<span class="category-icon"></span>
|
||||
<span class="category-name">Supplies</span>
|
||||
<span class="category-count">5</span>
|
||||
</button>
|
||||
@ -117,7 +117,7 @@
|
||||
<div class="panel-content">
|
||||
<div class="cart-items" id="cartItems">
|
||||
<div class="empty-cart">
|
||||
<span class="empty-icon">🛒</span>
|
||||
<span class="empty-icon"></span>
|
||||
<span class="empty-text">Your cart is empty</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -143,7 +143,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="store.js"></script>
|
||||
<!-- <script src="script.js"></script> -->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -8,36 +8,36 @@ const mockData = {
|
||||
balance: 45750,
|
||||
items: [
|
||||
// Weapons
|
||||
{ id: 1, name: "Assault Rifle", category: "weapons", icon: "🔫", description: "Standard military-grade rifle", price: 2500 },
|
||||
{ id: 2, name: "Sniper Rifle", category: "weapons", icon: "🎯", description: "Long-range precision weapon", price: 4500 },
|
||||
{ id: 3, name: "SMG", category: "weapons", icon: "🔫", description: "Close-quarters combat", price: 1800 },
|
||||
{ id: 4, name: "Pistol", category: "weapons", icon: "🔫", description: "Sidearm backup weapon", price: 800 },
|
||||
{ id: 5, name: "Shotgun", category: "weapons", icon: "🔫", description: "Close-range powerhouse", price: 1500 },
|
||||
{ id: 6, name: "LMG", category: "weapons", icon: "🔫", description: "Heavy suppression weapon", price: 3500 },
|
||||
{ id: 7, name: "Grenade Launcher", category: "weapons", icon: "💣", description: "Explosive ordnance", price: 5000 },
|
||||
{ id: 8, name: "Rocket Launcher", category: "weapons", icon: "🚀", description: "Anti-vehicle weapon", price: 8000 },
|
||||
{ id: 1, name: "Assault Rifle", category: "weapons", image: "", price: 2500 },
|
||||
{ id: 2, name: "Sniper Rifle", category: "weapons", image: "", price: 4500 },
|
||||
{ id: 3, name: "SMG", category: "weapons", image: "", price: 1800 },
|
||||
{ id: 4, name: "Pistol", category: "weapons", image: "", price: 800 },
|
||||
{ id: 5, name: "Shotgun", category: "weapons", image: "", price: 1500 },
|
||||
{ id: 6, name: "LMG", category: "weapons", image: "", price: 3500 },
|
||||
{ id: 7, name: "Grenade Launcher", category: "weapons", image: "", price: 5000 },
|
||||
{ id: 8, name: "Rocket Launcher", category: "weapons", image: "", price: 8000 },
|
||||
|
||||
// Equipment
|
||||
{ id: 9, name: "Body Armor", category: "equipment", icon: "🎽", description: "Ballistic protection", price: 3000 },
|
||||
{ id: 10, name: "Helmet", category: "equipment", icon: "⛑️", description: "Head protection", price: 1200 },
|
||||
{ id: 11, name: "Night Vision", category: "equipment", icon: "🕶️", description: "See in the dark", price: 2500 },
|
||||
{ id: 12, name: "GPS Device", category: "equipment", icon: "📡", description: "Navigation system", price: 800 },
|
||||
{ id: 13, name: "Radio", category: "equipment", icon: "📻", description: "Team communication", price: 600 },
|
||||
{ id: 14, name: "Backpack", category: "equipment", icon: "🎒", description: "Extra storage capacity", price: 500 },
|
||||
{ id: 9, name: "Body Armor", category: "equipment", image: "", price: 3000 },
|
||||
{ id: 10, name: "Helmet", category: "equipment", image: "", price: 1200 },
|
||||
{ id: 11, name: "Night Vision", category: "equipment", image: "", price: 2500 },
|
||||
{ id: 12, name: "GPS Device", category: "equipment", image: "", price: 800 },
|
||||
{ id: 13, name: "Radio", category: "equipment", image: "", price: 600 },
|
||||
{ id: 14, name: "Backpack", category: "equipment", image: "", price: 500 },
|
||||
|
||||
// Medical
|
||||
{ id: 15, name: "First Aid Kit", category: "medical", icon: "💊", description: "Basic medical supplies", price: 400 },
|
||||
{ id: 16, name: "Med Kit", category: "medical", icon: "⚕️", description: "Advanced medical kit", price: 1000 },
|
||||
{ id: 17, name: "Bandages", category: "medical", icon: "🩹", description: "Stop bleeding", price: 150 },
|
||||
{ id: 18, name: "Morphine", category: "medical", icon: "💉", description: "Pain management", price: 300 },
|
||||
{ id: 19, name: "Blood Bag", category: "medical", icon: "🩸", description: "Restore blood level", price: 500 },
|
||||
{ id: 15, name: "First Aid Kit", category: "medical", image: "", price: 400 },
|
||||
{ id: 16, name: "Med Kit", category: "medical", image: "", price: 1000 },
|
||||
{ id: 17, name: "Bandages", category: "medical", image: "", price: 150 },
|
||||
{ id: 18, name: "Morphine", category: "medical", image: "", price: 300 },
|
||||
{ id: 19, name: "Blood Bag", category: "medical", image: "", price: 500 },
|
||||
|
||||
// Supplies
|
||||
{ id: 20, name: "Ammunition Box", category: "supplies", icon: "📦", description: "Mixed ammunition", price: 800 },
|
||||
{ id: 21, name: "Explosive Charges", category: "supplies", icon: "💣", description: "Demolition supplies", price: 1500 },
|
||||
{ id: 22, name: "Toolkit", category: "supplies", icon: "🔧", description: "Repair equipment", price: 600 },
|
||||
{ id: 23, name: "Food Rations", category: "supplies", icon: "🥫", description: "Emergency supplies", price: 200 },
|
||||
{ id: 24, name: "Water Canteen", category: "supplies", icon: "🧃", description: "Hydration supply", price: 150 }
|
||||
{ id: 20, name: "Ammunition Box", category: "supplies", image: "", price: 800 },
|
||||
{ id: 21, name: "Explosive Charges", category: "supplies", image: "", price: 1500 },
|
||||
{ id: 22, name: "Toolkit", category: "supplies", image: "", price: 600 },
|
||||
{ id: 23, name: "Food Rations", category: "supplies", image: "", price: 200 },
|
||||
{ id: 24, name: "Water Canteen", category: "supplies", image: "", price: 150 }
|
||||
]
|
||||
};
|
||||
|
||||
@ -64,7 +64,7 @@ function setupEventHandlers() {
|
||||
if (closeBtn) {
|
||||
closeBtn.addEventListener('click', () => {
|
||||
console.log('Closing store...');
|
||||
sendEvent('actor::close::store', {});
|
||||
sendEvent('store::close', {});
|
||||
});
|
||||
}
|
||||
|
||||
@ -136,8 +136,7 @@ function renderItems() {
|
||||
|
||||
if (searchQuery) {
|
||||
filteredItems = filteredItems.filter(item =>
|
||||
item.name.toLowerCase().includes(searchQuery) ||
|
||||
item.description.toLowerCase().includes(searchQuery)
|
||||
item.name.toLowerCase().includes(searchQuery)
|
||||
);
|
||||
}
|
||||
|
||||
@ -147,9 +146,8 @@ function renderItems() {
|
||||
card.className = 'item-card';
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="item-icon">${item.icon}</div>
|
||||
<div class="item-image"><img src="${item.image}" alt="${item.name}"></div>
|
||||
<div class="item-name">${item.name}</div>
|
||||
<div class="item-description">${item.description}</div>
|
||||
<div class="item-price">$${item.price.toLocaleString()}</div>
|
||||
<div class="item-actions">
|
||||
<button class="add-to-cart-btn" data-item-id="${item.id}">Add to Cart</button>
|
||||
@ -207,7 +205,7 @@ function renderCart() {
|
||||
if (cart.length === 0) {
|
||||
cartItems.innerHTML = `
|
||||
<div class="empty-cart">
|
||||
<span class="empty-icon">🛒</span>
|
||||
<span class="empty-icon"></span>
|
||||
<span class="empty-text">Your cart is empty</span>
|
||||
</div>
|
||||
`;
|
||||
@ -266,7 +264,7 @@ function handleCheckout() {
|
||||
const grandTotal = total + tax;
|
||||
|
||||
if (grandTotal > mockData.balance) {
|
||||
alert('Insufficient funds!');
|
||||
// alert('Insufficient funds!');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -283,7 +281,7 @@ function handleCheckout() {
|
||||
};
|
||||
|
||||
console.log('Purchase request:', purchaseData);
|
||||
sendEvent('actor::store::purchase', purchaseData);
|
||||
sendEvent('store::purchase', purchaseData);
|
||||
|
||||
// Clear cart after purchase
|
||||
cart = [];
|
||||
@ -128,7 +128,7 @@ body {
|
||||
}
|
||||
|
||||
.cart-icon {
|
||||
font-size: 1.25rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.cart-count {
|
||||
@ -202,7 +202,6 @@ body {
|
||||
.panel-content {
|
||||
flex: 1;
|
||||
padding: 1.5rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Custom Scrollbar */
|
||||
@ -312,6 +311,8 @@ body {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
gap: 1rem;
|
||||
overflow-y: auto;
|
||||
height: 590px;
|
||||
}
|
||||
|
||||
.item-card {
|
||||
@ -324,7 +325,8 @@ body {
|
||||
transition: all 0.15s ease;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
gap: 0.5rem;
|
||||
height: 300px !important;
|
||||
}
|
||||
|
||||
.item-card:hover {
|
||||
@ -335,8 +337,8 @@ body {
|
||||
inset 0 0 20px rgba(100, 150, 200, 0.05);
|
||||
}
|
||||
|
||||
.item-icon {
|
||||
font-size: 3rem;
|
||||
.item-image {
|
||||
height: 256px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user