Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

[ NARZĘDZIE ] Generator Zbroji ITEMPROTO


Rekomendowane odpowiedzi

Opublikowano

[GENERATOR ZBROJI ITEMPROTO]

 

Siemano 👋

 

Miałem do dodania sporo setów i dla uproszczenia pracy zrobiłem sobie taki generator query do sql dla zbroji może komuś się przyda więc łapcie  :

 

 

🛠️ Podstawy : Vnum(ID) , Nazwa (LocaleName) , Value3(ShapeIndex) , Wymagany Poziom , Obrona , Sloty KD , Bon 1,2,3 , ANTIFLAGI

 

 

🛠️ Główne funkcje :

  • Dwa tryby pracy : Generowanie pojedynczego przedmiotu lub od razu całego setu (Wojownik, Ninja, Sura, Szaman)

  • Auto VNUM (+1) : W trybie setu wpisujesz ID dla wojownika, a narzędzie samo nadaje kolejne ID dla reszty klas

  • W pełni konfigurowalny : W zakładkach możecie dodawać własne ID bonusów (APPLY_...) oraz Antiflagi. Generator sam oblicza sumę bitową antiflag (np. 1 << 15 zamienia na wartości dla bazy danych)

  • Własna struktura SQL : Jeśli Wasze item_proto w bazie ma inną strukturę kolumn, możecie edytować wzór zapytania INSERT INTO bezpośrednio w generatorze

  • Zapisywanie konfiguracji : Ustawiłeś pod swój serwer całą listę bonusów? Kliknij "Zapisz", a generator wypluje Ci nowy plik .html z już zapisaną Twoją bazą danych

 

 

Mój config był robiony pod TERENZO 2024 jeśli masz inne definicje antiflag, bonusów, inną strukturę sql trzeba konfigurować

 

Lista bonusów serwra jest w :  common / length.h w linii enum EApplyTypes

 

Lista ANTIFLAG serwera jest w : common / item_length.h w linii enum EItemFlag

 

 

 

📷 Zrzuty ekranu :

 


Pojedyncza Zbroja :

 

Spoiler

nullimage.png

 

Generuj Set :

 

Spoiler

set.PNG

 

CONFIG : 

 

Struktura SQL :

 

Spoiler

sql.PNG

 

Definicje Bonusów : 

 

Spoiler

bony.PNG

 

Definicje Antiflag : 

 

Spoiler

antiflagi.PNG

 

KOD GENERATORA :

 

- Otwieramy nowy notatnik

 

- Wklejamy kod

 

- Zapisujemy jako .html

 

- Gotowy plik wrzucamy w przeglądarkę

 

 

Spoiler

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>ItemProto Generator Zbroji </title>
    <style>
        :root { --accent: #38bdf8; --bg: #0f172a; --card: #1e293b; --input: #334155; }
        body { font-family: 'Segoe UI', sans-serif; background: var(--bg); color: #f8fafc; padding: 20px; display: flex; flex-direction: column; align-items: center; }
        .container { background: var(--card); border-radius: 12px; padding: 25px; width: 1150px; box-shadow: 0 10px 30px rgba(0,0,0,0.5); }
        h2 { color: var(--accent); text-align: center; border-bottom: 2px solid var(--accent); padding-bottom: 10px; margin-top:0; }
        
        /* ZAKŁADKI */
        .tabs { display: flex; gap: 5px; margin-bottom: 20px; background: #020617; padding: 5px; border-radius: 8px; }
        .tab-btn { flex: 1; padding: 10px; border: none; background: transparent; color: #94a3b8; cursor: pointer; border-radius: 6px; font-weight: bold; transition: 0.3s; }
        .tab-btn.active { background: var(--accent); color: var(--bg); }
        .tab-content { display: none; border-top: 1px solid #444; padding-top: 20px; }
        .tab-content.active { display: block; }

        /* LISTY KONFIGURACJI */
        .config-list { background: var(--input); padding: 15px; border-radius: 8px; max-height: 500px; overflow-y: auto; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
        .config-item { display: flex; gap: 10px; background: #1e293b; padding: 5px; border-radius: 4px; align-items: center; }
        .btn-add { background: #2ecc71; color: white; border: none; padding: 8px 15px; border-radius: 4px; cursor: pointer; margin-bottom: 10px; font-weight: bold; }
        .btn-del { background: #e74c3c; color: white; border: none; padding: 5px 8px; border-radius: 4px; cursor: pointer; }

        /* GŁÓWNY GENERATOR */
        .mode-selector { background: var(--input); padding: 15px; border-radius: 8px; margin-bottom: 20px; display: flex; justify-content: center; align-items: center; gap: 25px; border: 1px solid var(--accent); }
        .mode-selector label { cursor: pointer; font-weight: bold; color: var(--accent); display: flex; align-items: center; gap: 8px; font-size: 14px; }
        #vnum_sync_wrapper { display: none; margin-left: 10px; padding-left: 20px; border-left: 2px solid #475569; }

        .armor-section { background: var(--card); border: 1px solid #444; border-radius: 8px; margin-bottom: 10px; overflow: hidden; }
        .armor-header { background: var(--input); padding: 12px 20px; cursor: pointer; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #444; transition: 0.3s; }
        .armor-header:hover { background: #475569; }
        .armor-header h3 { margin: 0; color: var(--accent); font-size: 14px; }
        
        .armor-content { padding: 20px; }
        .collapsed .armor-content { display: none; }

        /* SIATKA I POLA */
        .section-h { grid-column: span 3; color: #94a3b8; font-size: 12px; border-bottom: 1px solid #444; margin-top: 15px; padding-bottom: 5px; text-transform: uppercase; font-weight: bold; }
        .section-h:first-child { margin-top: 0; }
        
        .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; margin-bottom: 20px; }
        .input-group { background: var(--input); padding: 12px; border-radius: 8px; }
        label { display: block; font-size: 11px; margin-bottom: 5px; color: var(--accent); font-weight: bold; }
        input, select, textarea { width: 100%; padding: 8px; border-radius: 4px; border: none; background: #0f172a; color: white; box-sizing: border-box; font-size: 13px; }
        
        .checkbox-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; background: var(--input); padding: 15px; border-radius: 8px; }
        .check-item { background: #475569; padding: 8px 10px; border-radius: 4px; font-size: 11px; display: flex; align-items: center; cursor: pointer; transition: 0.2s; }
        .check-item:hover { background: #64748b; }
        input[type="checkbox"] { width: auto !important; margin-right: 8px; cursor: pointer; transform: scale(1.1); }
        
        /* WYNIK I PRZYCISKI */
        .output-area { background: #020617; padding: 20px; border-radius: 8px; border: 2px solid var(--accent); margin-top: 20px; }
        #sql_out { height: 180px; color: #2ecc71; font-family: monospace; font-size: 11px; resize: vertical; }
        
        .btn-main { background: var(--accent); color: var(--bg); border: none; padding: 15px; border-radius: 6px; font-weight: bold; cursor: pointer; width: 100%; font-size: 16px; margin-top:10px; transition: 0.2s; }
        .btn-main:hover { background: #0ea5e9; transform: translateY(-2px); }
        
        .btn-save-file { background: #f59e0b; color: var(--bg); border: none; padding: 15px; border-radius: 6px; font-weight: bold; cursor: pointer; width: 100%; font-size: 16px; margin-top: 10px; display: none; transition: 0.2s; }
        .btn-save-file:hover { background: #d97706; }
    </style>
</head>
<body>

<div class="container">
    <h2>ItemProto Generator Zbroji</h2>

    <div class="tabs">
        <button class="tab-btn active" onclick="openTab('gen')">GENERATOR</button>
        <button class="tab-btn" onclick="openTab('conf-sql')">STRUKTURA SQL</button>
        <button class="tab-btn" onclick="openTab('conf-bon')">DEFINICJE BONUSÓW</button>
        <button class="tab-btn" onclick="openTab('conf-af')">DEFINICJE ANTIFLAG</button>
    </div>

    <div id="gen" class="tab-content active">
        <div class="mode-selector">
            <label><input type="radio" name="mode" value="single" checked onclick="toggleMode()"> POJEDYNCZA ZBROJA</label>
            <label><input type="radio" name="mode" value="set" onclick="toggleMode()"> GENERUJ SET (4 KLASY)</label>
            <div id="vnum_sync_wrapper">
                <label title="Wpisz ID u Wojownika, a reszta dostanie ID o 1 większe"><input type="checkbox" id="vnum_sync" checked> AUTO VNUM (+1)</label>
            </div>
        </div>
        <div id="armors-wrapper"></div>
        <button class="btn-main" onclick="generateAll()">GENERUJ INSERTY SQL</button>
        <div class="output-area"><textarea id="sql_out" readonly placeholder="Gotowy kod SQL pojawi się tutaj..."></textarea></div>
    </div>

    <div id="conf-sql" class="tab-content">
        <div class="input-group">
            <label>Wzór kodu SQL dla INSERT INTO:</label>
            <textarea id="sql_struct" style="height: 150px;">INSERT INTO `item_proto` VALUES ('{vnum}', {hexN}, {hexL}, '2', '0', '0', '2', '{af}', '1', '1', '', '0', '0', '0', '0', '0', '0', '1', '{lv}', '0', '0', '{at0}', '{av0}', '{at1}', '{av1}', '{at2}', '{av2}', '0', '{def}', '0', '{v3}', '0', '0', '-1', '-1', '-1', '-1', '-1', '-1', '100', '{kdc}', '0');</textarea>
        </div>
    </div>

    <div id="conf-bon" class="tab-content">
        <button class="btn-add" onclick="addConfigRow('bon_list', '', '')">+ Dodaj Nowy Bonus</button>
        <div id="bon_list" class="config-list"></div>
    </div>

    <div id="conf-af" class="tab-content">
        <button class="btn-add" onclick="addConfigRow('af_list', '', '')">+ Dodaj Nową Antiflagę</button>
        <div id="af_list" class="config-list"></div>
    </div>

    <button id="btn-save-config" class="btn-save-file" onclick="downloadThisFile()">ZAPISZ KONFIGURACJĘ I POBIERZ PLIK .HTML</button>
</div>

<script id="data-holder">
    // START_DATA
    let configBonuses = [{"id":"0","name":"APPLY_NONE"},{"id":"1","name":"APPLY_MAX_HP"},{"id":"2","name":"APPLY_MAX_SP"},{"id":"3","name":"APPLY_CON"},{"id":"4","name":"APPLY_INT"},{"id":"5","name":"APPLY_STR"},{"id":"6","name":"APPLY_DEX"},{"id":"7","name":"APPLY_ATT_SPEED"},{"id":"8","name":"APPLY_MOV_SPEED"},{"id":"9","name":"APPLY_CAST_SPEED"},{"id":"10","name":"APPLY_HP_REGEN"},{"id":"11","name":"APPLY_SP_REGEN"},{"id":"12","name":"APPLY_POISON_PCT"},{"id":"13","name":"APPLY_STUN_PCT"},{"id":"14","name":"APPLY_SLOW_PCT"},{"id":"15","name":"APPLY_CRITICAL_PCT"},{"id":"16","name":"APPLY_PENETRATE_PCT"},{"id":"17","name":"APPLY_ATTBONUS_HUMAN"},{"id":"18","name":"APPLY_ATTBONUS_ANIMAL"},{"id":"19","name":"APPLY_ATTBONUS_ORC"},{"id":"20","name":"APPLY_ATTBONUS_MILGYO"},{"id":"21","name":"APPLY_ATTBONUS_UNDEAD"},{"id":"22","name":"APPLY_ATTBONUS_DEVIL"},{"id":"23","name":"APPLY_STEAL_HP"},{"id":"24","name":"APPLY_STEAL_SP"},{"id":"27","name":"APPLY_BLOCK"},{"id":"28","name":"APPLY_DODGE"},{"id":"29","name":"APPLY_RESIST_SWORD"},{"id":"30","name":"APPLY_RESIST_TWOHAND"},{"id":"31","name":"APPLY_RESIST_DAGGER"},{"id":"32","name":"APPLY_RESIST_BELL"},{"id":"33","name":"APPLY_RESIST_FAN"},{"id":"34","name":"APPLY_RESIST_BOW"},{"id":"37","name":"APPLY_RESIST_MAGIC"},{"id":"43","name":"APPLY_EXP_DOUBLE_BONUS"},{"id":"44","name":"APPLY_GOLD_DOUBLE_BONUS"},{"id":"45","name":"APPLY_ITEM_DROP_BONUS"},{"id":"48","name":"APPLY_IMMUNE_STUN"},{"id":"53","name":"APPLY_ATT_GRADE_BONUS"},{"id":"63","name":"APPLY_ATTBONUS_MONSTER"}];
    let configAntiflags = [{"id":"1","name":"ANTI_FEMALE"},{"id":"2","name":"ANTI_MALE"},{"id":"4","name":"ANTI_WARRIOR"},{"id":"8","name":"ANTI_ASSASSIN"},{"id":"16","name":"ANTI_SURA"},{"id":"32","name":"ANTI_SHAMAN"},{"id":"64","name":"ANTI_GET"},{"id":"128","name":"ANTI_DROP"},{"id":"256","name":"ANTI_SELL"},{"id":"512","name":"ANTI_EMPIRE_A"},{"id":"1024","name":"ANTI_EMPIRE_B"},{"id":"2048","name":"ANTI_EMPIRE_C"},{"id":"4096","name":"ANTI_SAVE"},{"id":"8192","name":"ANTI_GIVE"},{"id":"16384","name":"ANTI_PKDROP"},{"id":"32768","name":"ANTI_STACK"},{"id":"65536","name":"ANTI_MYSHOP"},{"id":"131072","name":"ANTI_SAFEBOX"}];
    // END_DATA

    function openTab(id) {
        document.querySelectorAll('.tab-content').forEach(t => t.classList.remove('active'));
        document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
        document.getElementById(id).classList.add('active');
        event.currentTarget.classList.add('active');
        
        // Pokaż przycisk zapisywania TYLKO w zakładkach konfiguracyjnych
        const saveBtn = document.getElementById('btn-save-config');
        if(id === 'gen') saveBtn.style.display = 'none';
        else saveBtn.style.display = 'block';
    }

    function addConfigRow(containerId, idVal, nameVal) {
        const div = document.createElement('div');
        div.className = 'config-item';
        div.innerHTML = `
            <input type="number" class="cfg-id" value="${idVal}" style="width:70px">
            <input type="text" class="cfg-name" value="${nameVal}">
            <button class="btn-del" onclick="this.parentElement.remove()">X</button>
        `;
        document.getElementById(containerId).appendChild(div);
    }

    function getLiveConfig() {
        const b = [], a = [];
        document.querySelectorAll('#bon_list .config-item').forEach(row => {
            b.push({id: row.querySelector('.cfg-id').value, name: row.querySelector('.cfg-name').value});
        });
        document.querySelectorAll('#af_list .config-item').forEach(row => {
            a.push({id: row.querySelector('.cfg-id').value, name: row.querySelector('.cfg-name').value});
        });
        return { bonuses: b, antiflags: a };
    }

    function toggleMode() {
        const mode = document.querySelector('input[name="mode"]:checked').value;
        const wrapper = document.getElementById('armors-wrapper');
        const syncWrapper = document.getElementById('vnum_sync_wrapper');
        
        wrapper.innerHTML = '';
        const cfg = getLiveConfig();
        
        if (mode === 'single') {
            syncWrapper.style.display = 'none'; // Ukryj Auto VNUM
            wrapper.appendChild(createArmorSection(0, true, cfg));
        } else {
            syncWrapper.style.display = 'block'; // Pokaż Auto VNUM
            for (let i = 0; i < 4; i++) {
                wrapper.appendChild(createArmorSection(i, false, cfg));
            }
        }
    }

    function createArmorSection(index, isSingle, cfg) {
        const classes = ["Wojownik", "Ninja", "Sura", "Szaman"];
        const section = document.createElement('div');
        section.className = `armor-section ${(!isSingle && index > 0) ? 'collapsed' : ''}`;
        section.id = `section_${index}`;
        
        // Domyślne antiflagi dla poszczególnych klas w secie
        const autoAF = [ [8,16,32,32768], [4,16,32,32768], [4,8,32,32768], [4,8,16,32768] ];

        section.innerHTML = `
            ${isSingle ? '' : `<div class="armor-header" onclick="this.parentElement.classList.toggle('collapsed')"><h3>ZBROJA DLA: ${classes[index].toUpperCase()}</h3><span>[Kliknij aby rozwinąć/zwinąć]</span></div>`}
            <div class="armor-content">
                <div class="grid">
                    <div class="section-h">PODSTAWY</div>
                    <div class="input-group"><label>VNUM (ID):</label><input type="number" class="vnum" value="${164500+index}" oninput="syncV(this,${index})"></div>
                    <div class="input-group"><label>Nazwa (Locale Name):</label><input type="text" class="loc_name" value="Zbroja ${isSingle?'Nowa':classes[index]}"></div>
                    <div class="input-group"><label>Value3 (ShapeIndex):</label><input type="number" class="v3" value="${index}"></div>
                    
                    <div class="section-h">STATYSTYKI</div>
                    <div class="input-group"><label>Wymagany Poziom:</label><input type="number" class="lv" value="100"></div>
                    <div class="input-group"><label>Obrona:</label><input type="number" class="def" value="100"></div>
                    <div class="input-group"><label>Sloty KD:</label><input type="number" class="kdc" value="3"></div>
                    
                    <div class="section-h">BONUSY STAŁE</div>
                    ${[0,1,2].map(i => `
                        <div class="input-group">
                            <label>Bonus ${i+1}:</label>
                            <select class="at${i}">${cfg.bonuses.map(b => `<option value="${b.id}">${b.name} (${b.id})</option>`).join('')}</select>
                            <input type="number" class="av${i}" value="0" style="margin-top:5px" placeholder="Wartość">
                        </div>
                    `).join('')}
                </div>
                
                <div style="margin-bottom: 10px; color: #94a3b8; font-size: 12px; border-bottom: 1px solid #444; padding-bottom: 5px; text-transform: uppercase; font-weight: bold;">ANTIFLAGI (Zaznacz czego ma nie mieć)</div>
                <div class="checkbox-grid">
                    ${cfg.antiflags.map(af => `
                        <label class="check-item">
                            <input type="checkbox" class="bit" value="${af.id}" ${(!isSingle && autoAF[index].includes(parseInt(af.id))) ? 'checked' : ''}> ${af.name}
                        </label>
                    `).join('')}
                </div>
            </div>
        `;
        return section;
    }

    function syncV(el, idx) {
        const mode = document.querySelector('input[name="mode"]:checked').value;
        if(mode === 'set' && idx === 0 && document.getElementById('vnum_sync').checked) {
            document.querySelectorAll('.vnum').forEach((inp, i) => { if(i>0) inp.value = parseInt(el.value)+i; });
        }
    }

    function generateAll() {
        const struct = document.getElementById('sql_struct').value;
        let finalSql = "";
        
        document.querySelectorAll('.armor-section').forEach(sec => {
            let afSum = 0; 
            sec.querySelectorAll('.bit:checked').forEach(c => afSum += parseInt(c.value));
            
            const data = {
                vnum: sec.querySelector('.vnum').value,
                hexN: "0x"+Array.from(sec.querySelector('.vnum').value).map(c=>c.charCodeAt(0).toString(16)).join(""),
                hexL: "0x"+Array.from(sec.querySelector('.loc_name').value).map(c=>c.charCodeAt(0).toString(16)).join(""),
                v3: sec.querySelector('.v3').value, 
                lv: sec.querySelector('.lv').value,
                def: sec.querySelector('.def').value, 
                kdc: sec.querySelector('.kdc').value,
                af: afSum,
                at0: sec.querySelector('.at0').value, av0: sec.querySelector('.av0').value,
                at1: sec.querySelector('.at1').value, av1: sec.querySelector('.av1').value,
                at2: sec.querySelector('.at2').value, av2: sec.querySelector('.av2').value
            };
            
            let line = struct;
            for(let key in data) line = line.replace(new RegExp(`{${key}}`, 'g'), data[key]);
            finalSql += line + "\n";
        });
        
        document.getElementById('sql_out').value = finalSql;
    }

    function downloadThisFile() {
        const cfg = getLiveConfig();
        const sqlPattern = document.getElementById('sql_struct').value;
        let content = document.documentElement.outerHTML;
        
        const newData = `let configBonuses = ${JSON.stringify(cfg.bonuses)};\n    let configAntiflags = ${JSON.stringify(cfg.antiflags)};`;
        content = content.replace(/\/\/ START_DATA[\s\S]*?\/\/ END_DATA/, `// START_DATA\n    ${newData}\n    // END_DATA`);
        content = content.replace(/<textarea id="sql_struct"[\s\S]*?>[\s\S]*?<\/textarea>/, `<textarea id="sql_struct" style="height: 150px;">${sqlPattern}</textarea>`);
        
        const blob = new Blob([content], {type: 'text/html'});
        const a = document.createElement('a');
        a.href = URL.createObjectURL(blob);
        a.download = 'ItemProto_Generator_Zbroji_NEWCONF.html';
        a.click();
    }

    window.onload = () => {
        configBonuses.forEach(b => addConfigRow('bon_list', b.id, b.name));
        configAntiflags.forEach(a => addConfigRow('af_list', a.id, a.name));
        toggleMode();
    };
</script>

</body>
</html>

 

 

Kopiujemy Query które dał nam generator : 

 

- Klikamy na Player w Navicat 

 

- Na górze Query

 

- Add new Query

 

- Wklejamy 

 

- RUN

 

I sprawdzamy czy wpisy dodały się w item_proto 

 

 

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Zaloguj się poniżej.

Zaloguj się
×
×
  • Dodaj nową pozycję...