/* PRIMAL RAMPAGE — game data: weapons, heroes, skins, beasts, alphas, cards. Theme: prehistoric tribe survival vs dinosaurs. Original content. NOTE: ids stay stable so existing saved profiles keep working; `kind` selects the drawn sprite in js/art.js */ (function () { 'use strict'; var US = (window.US = window.US || {}); /* ---------------- Weapons ---------------- */ US.WEAPONS = { pistol: { id: 'pistol', name: 'Slingshot', price: 0, kind: 'slingshot', dmg: 12, rof: 3.2, speed: 620, pellets: 1, spread: 0.04, pierce: 0, color: '#c9bda6', size: 4, sfx: 'shoot' }, smg: { id: 'smg', name: 'Bone Blowpipe', price: 400, kind: 'blowpipe', dmg: 7, rof: 8.5, speed: 700, pellets: 1, spread: 0.13, pierce: 0, color: '#caa96a', size: 3.5, sfx: 'smg' }, shotgun: { id: 'shotgun', name: 'Spear Burst', price: 750, kind: 'spears', dmg: 8, rof: 1.5, speed: 560, pellets: 6, spread: 0.38, pierce: 0, color: '#a8814f', size: 4, sfx: 'shotgun', knock: 120 }, rail: { id: 'rail', name: 'Obsidian Lance', price: 1200, kind: 'obelisk', dmg: 46, rof: 1.1, speed: 1500, pellets: 1, spread: 0, pierce: 3, color: '#7b6fa0', size: 5, sfx: 'rail' }, launcher: { id: 'launcher', name: 'Fire Bomb Thrower', price: 1800, kind: 'firebomb', dmg: 30, rof: 0.9, speed: 430, pellets: 1, spread: 0.05, pierce: 0, color: '#e04b3a', size: 7, sfx: 'rocket', aoe: 90 } }; /* ---------------- Heroes ---------------- */ US.HEROES = { recruit: { id: 'recruit', name: 'Raider', price: 0, hp: 100, speed: 250, dmgMul: 1, talent: '+0 — cân bằng / balanced', tint: '#e04b3a' }, scout: { id: 'scout', name: 'Trail Runner', price: 500, hp: 75, speed: 320, dmgMul: 0.9, talent: '+28% tốc độ / speed — mỏng máu / frail', tint: '#58a55c' }, brute: { id: 'brute', name: 'Bear-Clan Brute', price: 900, hp: 160, speed: 205, dmgMul: 1.25, talent: 'Trâu bò, đòn nặng, chậm / tanky, heavy, slow', tint: '#ffb938' }, gunslinger: { id: 'gunslinger', name: 'Spirit Hunter', price: 1400, hp: 90, speed: 265, dmgMul: 1.05, talent: '+15% chí mạng ×2.5 / crit chance', crit: 0.15, critMul: 2.5, tint: '#c56cf0' } }; /* ---------------- Skins (war-paint palettes) ---------------- */ US.SKINS = { default: { id: 'default', name: 'Clay', price: 0, body: '#e04b3a', trim: '#e8dcc4' }, ember: { id: 'ember', name: 'Ember', price: 300, body: '#ff8a3d', trim: '#ffd9a0' }, frost: { id: 'frost', name: 'Glacier', price: 300, body: '#9fd8ff', trim: '#e8fbff' }, void: { id: 'void', name: 'Night Shade', price: 600, body: '#a86bff', trim: '#e2ccff' }, gold: { id: 'gold', name: 'Sun Chief', price: 900, body: '#ffb938', trim: '#fff3c4' }, crimson: { id: 'crimson', name: 'Blood Moon', price: 900, body: '#c22f45', trim: '#ffc2c8' }, // --- premium tier, bought with Ngọn Lửa (hard currency) --- ashfang: { id: 'ashfang', name: 'Ashfang Chief', price: 0, gems: 15, body: '#5a4a3c', trim: '#ff6b35', premium: true, vi: 'Thủ Lĩnh Tro Tàn — hào quang núi lửa' }, jade: { id: 'jade', name: 'Jade Serpent', price: 0, gems: 25, body: '#2fae7a', trim: '#d9ffe9', premium: true, vi: 'Trăn Bích Ngọc — da rắn thần rừng' }, solaris: { id: 'solaris', name: 'Solaris', price: 0, gems: 40, body: '#ffd24a', trim: '#fff8dd', premium: true, glow: true, vi: 'Thái Dương — ánh sáng nguyên thủy' } }; /* ---------------- Beasts ---------------- */ // contact = dps on touch; value feeds heat/score; cost feeds wave budget US.ENEMIES = { grunt: { id: 'grunt', art: 'raptor', hp: 30, speed: 95, radius: 14, contact: 12, value: 1, cost: 10, coin: [1, 2], color: '#5f8f3e', score: 10, fromWave: 1 }, runner: { id: 'runner', art: 'compy', hp: 16, speed: 185, radius: 11, contact: 9, value: 1, cost: 12, coin: [1, 2], color: '#d98e2b', score: 12, fromWave: 2 }, spitter: { id: 'spitter', art: 'dilo', hp: 34, speed: 70, radius: 13, contact: 8, value: 2, cost: 22, coin: [2, 3], color: '#8ac74a', score: 20, fromWave: 3, ranged: { dmg: 10, speed: 240, rof: 1.6, range: 380 } }, tank: { id: 'tank', art: 'trike', hp: 130, speed: 55, radius: 22, contact: 22, value: 3, cost: 40, coin: [4, 7], color: '#8a7a5c', score: 35, fromWave: 4 }, stego: { id: 'stego', art: 'stego', hp: 90, speed: 60, radius: 19, contact: 18, value: 2, cost: 34, coin: [3, 5], color: '#6f7d44', score: 30, fromWave: 7 }, pachy: { id: 'pachy', art: 'pachy', hp: 45, speed: 120, radius: 13, contact: 14, value: 2, cost: 26, coin: [2, 4], color: '#b5893e', score: 28, fromWave: 5, dash: { speed: 340, dur: 0.45, cd: 2.6 } }, splitter: { id: 'splitter', art: 'ptero', hp: 60, speed: 85, radius: 18, contact: 14, value: 2, cost: 30, coin: [2, 4], color: '#7ba3a8', score: 25, fromWave: 6, splits: { into: 'mini', count: 3 } }, mini: { id: 'mini', art: 'pteroChick', hp: 14, speed: 165, radius: 9, contact: 7, value: 0.5, cost: 0, coin: [1, 1], color: '#93b7bb', score: 6, noSpawn: true }, eliteGrunt: { id: 'eliteGrunt', art: 'alphaRaptor', hp: 110, speed: 105, radius: 17, contact: 16, value: 3, cost: 45, coin: [6, 9], color: '#b0432e', score: 50, elite: true, fromWave: 8 } }; US.BOSSES = [ { id: 'bruiser', art: 'rex', name: 'REX THE ELDER', hp: 1600, speed: 80, radius: 44, contact: 30, color: '#7e4022', score: 500, coin: [40, 60], patterns: ['charge', 'spawn'] }, { id: 'artillery', art: 'spino', name: 'SPINO OF THE REEDS', hp: 2000, speed: 55, radius: 46, contact: 24, color: '#4f6f52', score: 650, coin: [50, 75], patterns: ['radial', 'aimed', 'spiral'] }, { id: 'hydra', art: 'giga', name: 'GIGA BROODMOTHER', hp: 2600, speed: 70, radius: 42, contact: 26, color: '#55514e', score: 800, coin: [60, 90], patterns: ['split', 'charge'] } ]; /* ---------------- Upgrade cards ---------------- */ // apply(p) mutates player stats; stack limits where noted. US.CARDS = [ { id: 'dmg', rarity: 'common', max: 99, icon: '🦷', title: 'Sharpened Fangs', desc: '+25% damage / sát thương', apply: function (s) { s.dmgMul += 0.25; } }, { id: 'rof', rarity: 'common', max: 99, icon: '🖐', title: 'Quick Hands', desc: '+20% fire rate / tốc độ bắn', apply: function (s) { s.rofMul += 0.2; } }, { id: 'hp', rarity: 'common', max: 99, icon: '🦴', title: 'Thick Hide', desc: '+25 max HP & heal 50 / hồi 50', apply: function (s) { s.maxHp += 25; }, onPick: function (pl) { pl.hp = Math.min(pl.stats.maxHp, pl.hp + 50); } }, { id: 'speed', rarity: 'common', max: 5, icon: '👣', title: 'Fleet Foot', desc: '+15% move speed / di chuyển', apply: function (s) { s.speedMul += 0.15; } }, { id: 'multi', rarity: 'epic', max: 4, icon: '🔱', title: 'Twin Arms', desc: '+1 projectile / thêm 1 phát', apply: function (s) { s.pellets += 1; } }, { id: 'pierce', rarity: 'rare', max: 4, icon: '➶', title: 'Skewer', desc: 'Bullets pierce +1 / xuyên thêm 1', apply: function (s) { s.pierce += 1; } }, { id: 'crit', rarity: 'rare', max: 6, icon: '✦', title: 'Deadeye', desc: '+10% crit chance / chí mạng', apply: function (s) { s.crit += 0.10; } }, { id: 'critdmg', rarity: 'rare', max: 4, icon: '✸', title: 'Executioner', desc: '+50% crit damage / sát thương chí mạng', apply: function (s) { s.critMul += 0.5; } }, { id: 'leech', rarity: 'epic', max: 4, icon: '🩸', title: 'Red Harvest', desc: 'Heal 3% of damage dealt / hút máu', apply: function (s) { s.lifesteal += 0.03; } }, { id: 'bspd', rarity: 'common', max: 4, icon: '💪', title: 'Strong Arm', desc: '+30% bullet speed / đạn bay nhanh', apply: function (s) { s.bulletSpeedMul += 0.3; } }, { id: 'magnet', rarity: 'common', max: 4, icon: '🧲', title: 'Hoarder', desc: '+80 pickup range / hút vật phẩm', apply: function (s) { s.magnet += 80; } }, { id: 'boom', rarity: 'epic', max: 3, icon: '🔥', title: 'Fire Bombs', desc: 'Bullets explode on hit / đạn nổ', apply: function (s) { s.explosive += 1; } }, { id: 'rico', rarity: 'epic', max: 2, icon: '🔄', title: 'Ricochet', desc: 'Bullets bounce to a new target / đạn nảy', apply: function (s) { s.ricochet += 1; } }, { id: 'bomb', rarity: 'rare', max: 99, icon: '💣', title: 'Bundle of Fire', desc: '+2 bombs now / nhận 2 bom', apply: function () {}, onPick: function (pl) { pl.bombs += 2; } }, { id: 'ultcharge', rarity: 'rare', max: 4, icon: '🌟', title: 'Ancestor Spirit', desc: '+40% ultimate charge rate / nạp chiêu nhanh', apply: function (s) { s.ultRate += 0.4; } }, { id: 'ultnow', rarity: 'epic', max: 99, icon: '☄', title: 'Spirit Call', desc: 'Ultimate fully charged / chiêu cuối đầy', apply: function () {}, onPick: function (pl) { pl.ult = 100; } }, { id: 'greed', rarity: 'common', max: 4, icon: '🪙', title: 'Shiny Things', desc: '+35% coins earned / nhiều vàng hơn', apply: function (s) { s.coinMul += 0.35; } }, { id: 'regen', rarity: 'rare', max: 4, icon: '🌿', title: "Healer's Ritual", desc: 'Regenerate +1.5 HP/s / hồi máu', apply: function (s) { s.regen += 1.5; } }, { id: 'thorns', rarity: 'rare', max: 3, icon: '🌵', title: 'Spiky Hide', desc: 'Damages enemies that touch you / gai phản đòn', apply: function (s) { s.thorns += 25; } }, { id: 'bigbullets', rarity: 'rare', max: 3, icon: '⬤', title: 'Boulder Shots', desc: '+40% bullet size & +10% damage / đạn to', apply: function (s) { s.bulletSizeMul += 0.4; s.dmgMul += 0.1; } } ]; /* ---------------- Permanent upgrades (spend amber, keep forever) ------ */ US.UPGRADES = { hp: { id: 'hp', max: 5, base: 120, per: '+10 máu tối đa / cấp', vi: 'Tim Sói Đầu', en: 'Wolf-Heart', apply: function (st, lv) { st.maxHp += lv * 10; } }, dmg: { id: 'dmg', max: 5, base: 180, per: '+6% sát thương / cấp', vi: 'Nọc Rắn Hổ', en: 'Viper Fangs', apply: function (st, lv) { st.dmgMul += lv * 0.06; } }, speed: { id: 'speed', max: 5, base: 150, per: '+3% tốc chạy / cấp', vi: 'Gót Gió', en: 'Wind Heels', apply: function (st, lv) { st.speedMul += lv * 0.03; } }, ult: { id: 'ult', max: 5, base: 200, per: '+10% hồi chiêu ultimate / cấp', vi: 'Mặt Trời Trẻ', en: 'Young Sun', apply: function (st, lv) { st.ultRate = (st.ultRate || 1) + lv * 0.1; } }, coin: { id: 'coin', max: 5, base: 160, per: '+5% hổ phách nhặt được / cấp', vi: 'Mắt Kền Kền', en: 'Vulture Eye', apply: function (st, lv) { st.coinMul = (st.coinMul || 1) + lv * 0.05; } }, bombs: { id: 'bombs', max: 2, base: 400, per: '+1 bom khởi đầu / cấp', vi: 'Túi Phù Thủy', en: 'Shaman Pouch', apply: function (st, lv) { st.startBombs = (st.startBombs || 0) + lv; } } }; /* ---------------- Bestiary: every beast of the valley ------------------ */ // goal kills to complete an entry; reward paid in ngọn lửa (gems) US.BESTIARY = { grunt: { name: { en: 'Green Raptor', vi: 'Raptor Xanh Lục' }, goal: 15, gem: 1, lore: { en: 'Fast pack hunter. Never alone.', vi: 'Săn theo bầy, nhanh như gió. Không bao giờ đi một mình.' } }, runner: { name: { en: 'Compy Scout', vi: 'Compy Dothám' }, goal: 20, gem: 1, lore: { en: 'Small, curious, bites your ankle.', vi: 'Nhỏ mà tinh, chuyên cắn gót chân.' } }, spitter: { name: { en: 'Dilophosaurus', vi: 'Khủng Long Có Mào' }, goal: 12, gem: 1, lore: { en: 'Spits venom from beyond spear range.', vi: 'Phun nọc từ xa hơn tầm giáo ném.' } }, tank: { name: { en: 'Triceratops', vi: 'Triceratops' }, goal: 8, gem: 2, lore: { en: 'A living battering ram with three horns.', vi: 'Con đập sống ba sừng, tường thành di động.' } }, stego: { name: { en: 'Stegosaurus', vi: 'Stegosaurus' }, goal: 8, gem: 2, lore: { en: 'Its tail spikes end arguments.', vi: 'Đuôi chùy bốn gai — kết thúc mọi tranh luận.' } }, pachy: { name: { en: 'Pachycephalosaurus', vi: 'Khủng Long Đầu Đội' }, goal: 10, gem: 2, lore: { en: 'Charges head-first. The skull is a weapon.', vi: 'Lao đầu như búa đá — hộp sọ là vũ khí.' } }, splitter: { name: { en: 'Pteranodon', vi: 'Pteranodon' }, goal: 10, gem: 2, lore: { en: 'Dive-bombers. Break one, three scream back.', vi: 'Chúng lao xuống từ trời. Đánh một, ba con gào lại.' } }, mini: { name: { en: 'Ptero Chick', vi: 'P Con' }, goal: 25, gem: 1, lore: { en: 'Hatched angry. Flies angrier.', vi: 'Nở ra đã giận, bay lên còn giận hơn.' } }, eliteGrunt: { name: { en: 'Alpha Raptor', vi: 'Raptor Đầu Đàn' }, goal: 6, gem: 3, lore: { en: 'Scarred leader of the pack.', vi: 'Thủ lĩnh đầy sẹo của bầy xanh.' } }, bruiser: { name: { en: 'REX THE ELDER', vi: 'REX GIÀ' }, goal: 3, gem: 5, lore: { en: 'The valley remembers his footsteps.', vi: 'Cả thung lũng nhớ tiếng bước chân của hắn.' } }, artillery: { name: { en: 'SPINO THE TIDE', vi: 'SPINO THỦY TRIỀU' }, goal: 3, gem: 5, lore: { en: 'A sail that blocks out the sun.', vi: 'Chiếc buồng chặn cả mặt trời.' } }, hydra: { name: { en: 'GIGA THE BROOD', vi: 'GIGA MA VẬT CHÚNG' }, goal: 3, gem: 8, lore: { en: 'Kill it and it multiplies. Kill those too.', vi: 'Giết nó thì nó sinh thêm. Giết nốt những đứa sinh ra.' } } }; /* ---------------- Daily quests (pick 3/day by date seed) --------------- */ // type hooks fired by the game: kill, collect, wave, ult, boss US.QUEST_POOL = [ { id: 'kill30', type: 'kill', goal: 30, gem: 1, coins: 80, text: { en: 'Slay 30 beasts', vi: 'Hạ 30 con thú' } }, { id: 'kill80', type: 'kill', goal: 80, gem: 2, coins: 200, text: { en: 'Slay 80 beasts', vi: 'Hạ 80 con thú' } }, { id: 'amber12', type: 'collect', goal: 12, gem: 1, coins: 60, text: { en: 'Collect 12 amber nuggets', vi: 'Nhặt 12 viên hổ phách' } }, { id: 'wave5', type: 'wave', goal: 5, gem: 2, coins: 150, text: { en: 'Reach wave 5 in one run', vi: 'Đạt wave 5 trong một trận' } }, { id: 'ult3', type: 'ult', goal: 3, gem: 1, coins: 70, text: { en: 'Unleash 3 ultimates', vi: 'Phóng 3 lần chiêu cuối' } }, { id: 'boss1', type: 'boss', goal: 1, gem: 3, coins: 250, text: { en: 'Defeat a boss', vi: 'Hạ 1 trùm khủng long' } } ]; /* ---------------- Achievements ----------------------------------------- */ US.ACHIEVEMENTS = { firstBlood: { gem: 1, test: function (sv, g) { return sv.stats.totalKills >= 1; }, text: { en: 'First Blood — slay your first beast', vi: 'Máu Đầu — hạ con thú đầu tiên' } }, slayer100: { gem: 2, test: function (sv) { return sv.stats.totalKills >= 100; }, text: { en: 'Beast Slayer — 100 kills total', vi: 'Thợ Săn — tổng 100 mạng' } }, slayer500: { gem: 4, test: function (sv) { return sv.stats.totalKills >= 500; }, text: { en: 'Apex Hunter — 500 kills total', vi: 'Thợ Săn Bậc Nhất — tổng 500 mạng' } }, wave5: { gem: 1, test: function (sv) { return sv.bestWave >= 5; }, text: { en: 'Face the Elder — reach wave 5', vi: 'Đối mặt Cố Nhân — đạt wave 5' } }, wave10: { gem: 2, test: function (sv) { return sv.bestWave >= 10; }, text: { en: 'Deep Jungle — reach wave 10', vi: 'Rừng Sâu — đạt wave 10' } }, wave25: { gem: 5, test: function (sv) { return sv.bestWave >= 25; }, text: { en: 'Valley Conqueror — finish wave 25', vi: 'Chinh Phục Thung Lũng — qua wave 25' } }, combo20: { gem: 2, test: function (g) { return g && g.bestCombo >= 20; }, text: { en: 'On Fire Master — combo ×20', vi: 'Bậc Thầy Bùng Cháy — combo ×20' } }, rich: { gem: 2, test: function (sv) { return sv.stats.totalAmber >= 300; }, text: { en: 'Amber Hoard — gather 300 amber', vi: 'Kho Hổ Phách — gom 300 hổ phách' } }, petParent: { gem: 3, test: function (sv) { return !!sv.pet; }, text: { en: 'Pack Parent — hatch a raptor egg', vi: 'Cha Mẹ Bầy Đàn — ấp trứng raptor' } }, endless10: { gem: 4, test: function (sv) { return sv.bestWave >= 30; }, text: { en: 'Beyond the Endless — wave 30+', vi: 'Vượt Vô Tận — wave 30+' } } }; US.RARITY_COLOR = { common: '#9c8a72', rare: '#58a55c', epic: '#ff8a3d' }; })();