Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // --- Grid helpers (unchanged) ---
- by = []
- bx = []
- acol = []
- atxt = []
- for (let i = 0; i < 800; i++) {
- bx.push(i % 40 - 20)
- by.push(Math.floor(i / 40) % 20 - 10)
- }
- // --- Sprites / types (unchanged) ---
- squarieNames = ["ypactl", "jesus_mata"]
- squarieMap = [
- ["[]##", [5, 5, 18, 18], [0, 1, 0, 1], [0, 0, -1, -1],
- "[7v7]###", [5, 5, 5, 18, 5, 5, 5, 18], [-2, -1, 0, 1, 2, -1, 0, 1], [0, 0, 0, 0, 0, -1, -1, -1],
- "[###]", [5, 18, 5, 5, 5], [-2, -1, 0, 1, 2, 0], [0, -1, -1, -1, 0],
- "[]##", [5, 5, 5, 5], [-1, 0, -1, 0], [0, 0, -1, -1]],
- ["J]", [4, 5], [0, 1], [-1, 0],
- "[o̮o]J", [7, 8, 25, 11, 13, 21], [-2, -1, 0, 1, 2, 0], [0, 0, 0, 0, 0, -1],
- "[]J", [4, 5, 7], [-2, 2, 0], [0, 0, -1],
- "[J", [8, 25], [-1, 0], [0, -1]]
- ]
- squarieHealth = [241, 4294967296]
- // --- ID generator fallback ---
- let _idCounter = 0
- function makeId() {
- if (typeof crypto !== "undefined" && crypto.randomUUID) return crypto.randomUUID()
- _idCounter++
- return "sq-" + Date.now().toString(36) + "-" + (_idCounter)
- }
- // --- Squarie list (objects with stats inside) ---
- let squaries = [
- {
- id: makeId(),
- type: 0,
- dir: 1,
- x: 10,
- y: 5,
- vx: 0,
- vy: 0,
- health: squarieHealth[0],
- damage: 0,
- kills: 0
- },
- {
- id: makeId(),
- type: 1,
- dir: 2,
- x: 30,
- y: 15,
- vx: 0,
- vy: 0,
- health: squarieHealth[1],
- damage: 0,
- kills: 0
- }
- ]
- // --- Text + objects ---
- text = [
- ["Squarie Playground v . .", 7, 0, 0, 4294967296],
- ["1", 11, 20, 0, 4294967296],
- ["2", 9, 22, 0, 4294967296],
- ["3", 4, 24, 0, 4294967296]
- ]
- // objects: { type: 0|1|2, x, y, angle?, owner? }
- objects = [
- { type: 1, x: 7, y: 13 },
- { type: 1, x: 39, y: 15 },
- { type: 1, x: 38, y: 17 }
- ]
- // --- Speed Control ---
- let speedMultiplier = 0.1
- let running = true
- function mod(x, y) {
- return x - (Math.floor(x / y) * y)
- }
- // --- Main update loop (physics, collisions, drawing) ---
- function update() {
- if (!running) return
- // decay text lifetime
- text = text.filter(t => t[4] - 0.0625 > 0).map(t =>
- [t[0], t[1], t[2], t[3], t[4] - 0.0625]
- )
- // remove "cleared" objects (type 0)
- objects = objects.filter(o => o.type !== 0)
- // --- Bullet collision ---
- for (let i = 0; i < objects.length; i++) {
- let obj = objects[i]
- if (obj.type === 2) {
- for (let j = 0; j < squaries.length; j++) {
- let s = squaries[j]
- if (s.health <= 0) continue
- if (
- mod(Math.round(obj.x), 40) === mod(Math.round(s.x), 40) &&
- mod(Math.round(obj.y), 20) === mod(Math.round(s.y), 20)
- ) {
- let dmg = Math.random() * 50 + 50
- s.health -= dmg
- // attribute damage and kills to owner id (if still present)
- let owner = squaries.find(ss => ss.id === obj.owner)
- if (owner) {
- owner.damage += dmg
- if (s.health <= 0) {
- owner.kills++
- }
- }
- // apply knockback
- if (typeof obj.angle === "number") {
- s.vx += Math.sin(obj.angle)
- s.vy += Math.cos(obj.angle)
- }
- text.push([Math.round(dmg) + " DMG", 4, s.x, s.y, 5])
- obj.type = 0 // mark consumed
- break // bullet consumed, stop checking other squaries
- }
- }
- }
- }
- // --- Movement + shooting ---
- for (let s of squaries) {
- if (s.health <= 0) continue
- s.x = mod(s.x + s.vx * speedMultiplier, 40)
- s.y = mod(s.y + s.vy * speedMultiplier, 20)
- s.vx /= Math.pow(1.1, speedMultiplier)
- s.vy /= Math.pow(1.1, speedMultiplier)
- if (Math.random() < 0.01) {
- let dir = Math.floor(Math.random() * 4)
- s.dir = dir
- s.vx += Math.random() * ((dir == 3) - (dir == 0))
- s.vy += Math.random() * ((dir == 1) - (dir == 2))
- }
- // squarie type 1 sometimes fires
- if (s.type === 1 && Math.random() < 0.003) {
- objects.push({
- type: 2,
- x: s.x + s.vx,
- y: s.y + s.vy,
- angle: [Math.PI / -2, 0, Math.PI, Math.PI / 2][s.dir] + Math.PI * (Math.random() - 0.5),
- owner: s.id
- })
- }
- }
- // --- Clear grid ---
- atxt = " ".repeat(800).split("")
- acol = atxt.map(v => 0)
- // --- Draw ASCII border ---
- for (let x = 0; x < 40; x++) {
- atxt[x] = (x === 0 ? "+" : (x === 39 ? "+" : "-"))
- atxt[x + 19 * 40] = (x === 0 ? "+" : (x === 39 ? "+" : "-"))
- acol[x] = 15
- acol[x + 19 * 40] = 15
- }
- for (let y = 1; y < 19; y++) {
- atxt[y * 40] = "|"
- atxt[y * 40 + 39] = "|"
- acol[y * 40] = 15
- acol[y * 40 + 39] = 15
- }
- // --- Draw squaries ---
- for (let s of squaries) {
- if (s.health <= 0) continue
- let rdr = squarieMap[s.type]
- for (let j = 0; j < rdr[s.dir * 4].length; j++) {
- let px = mod(Math.round(s.x + rdr[s.dir * 4 + 2][j]), 40)
- let py = mod(Math.round(s.y + rdr[s.dir * 4 + 3][j]), 20)
- atxt[px + py * 40] = rdr[s.dir * 4][j]
- acol[px + py * 40] = rdr[s.dir * 4 + 1][j]
- }
- }
- // --- Draw objects ---
- for (let o of objects) {
- if (o.type == 2) {
- if (o.angle === undefined) o.angle = Math.random() * 2 * Math.PI
- o.x += Math.sin(o.angle) * speedMultiplier
- o.y -= Math.cos(o.angle) * speedMultiplier
- }
- o.x = mod(o.x, 40)
- o.y = mod(o.y, 20)
- let ch = ["!", "0", "x"]
- let col = [4, 11, 13]
- let px = Math.round(o.x)
- let py = Math.round(o.y)
- atxt[px + py * 40] = ch[o.type]
- acol[px + py * 40] = col[o.type]
- }
- // --- Draw text labels ---
- for (let i = 0; i < text.length; i++) {
- for (let j = 0; j < text[i][0].length; j++) {
- let tx = mod(Math.round(text[i][2] + j), 40)
- let ty = mod(Math.round(text[i][3]), 20)
- atxt[tx + ty * 40] = text[i][0][j]
- acol[tx + ty * 40] = text[i][1]
- }
- }
- // --- Scoreboard at bottom lines ---
- let scoreboardStartY = 18
- for (let i = 0; i < squaries.length; i++) {
- let row = scoreboardStartY + i
- if (row >= 20) break
- let s = squaries[i]
- let scoreText = `S${i} HP:${Math.round(s.health)} Dmg:${Math.round(s.damage)} K:${s.kills}`
- for (let j = 0; j < scoreText.length && j < 40; j++) {
- let pos = j + row * 40
- atxt[pos] = scoreText[j]
- acol[pos] = 11
- }
- }
- requestAnimationFrame(update)
- }
- // start physics/render update
- update()
- // --- Compatibility helpers from your original environment ---
- // ct checks whether tile at (x,y) already shows a given char/color
- function ct(x, y, t, c) {
- if (typeof Tile !== "undefined" && Tile.exists(Math.floor(x / 20) * 20, Math.floor(y / 10) * 10)) {
- return (getCharInfoXY(x, y).char == t && getCharInfoXY(x, y).color == c)
- } else {
- return false
- }
- }
- // ap() writes the buffer to the display using writeCharAt and writeBuffer (your environment)
- function ap() {
- if (!running) return
- if (typeof writeBuffer === "undefined" || typeof writeCharAt === "undefined") {
- // If your environment doesn't expose writeBuffer/writeCharAt, skip and let update() handle logic.
- requestAnimationFrame(ap)
- return
- }
- if (writeBuffer.length < 50) {
- let i = 0
- for (let j = 0; j < 5; j++) {
- while (i < atxt.length && ct(bx[i], by[i], atxt[i], acol[i])) {
- i++
- }
- if (i < atxt.length) {
- writeCharAt(atxt[i], acol[i], bx[i], by[i])
- }
- }
- }
- requestAnimationFrame(ap)
- }
- ap()
- // --- Chat / command handlers (adapted to object shape) ---
- if (typeof w !== "undefined" && w.on) {
- w.on("msg", (data) => {
- let msg = data.msg.toLowerCase()
- if (msg.startsWith("spg#addsquarie")) {
- let na = data.msg.substring(15).trim()
- let idx = squarieNames.indexOf(na)
- if (idx !== -1) {
- let s = {
- id: makeId(),
- type: idx,
- dir: Math.floor(Math.random() * 4),
- x: Math.random() * 40,
- y: Math.random() * 20,
- vx: 0,
- vy: 0,
- health: squarieHealth[idx],
- damage: 0,
- kills: 0
- }
- squaries.push(s)
- setTimeout(() => w.chat.send("Added squarie " + na), 250)
- } else {
- let namsg = [
- na + " does not exist yet.",
- "Who is " + na + ", anyway?",
- "N\\A> " + na + "?",
- na + " is not available yet.",
- na + " tried to swim in lava.",
- na + " hit the ground too hard.",
- na + " blew up by a creeper",
- na + " died.",
- na.toUpperCase() + " WAS USED UP. " + data.nick.toUpperCase() + " WAS USED UP.",
- na + "? Nah, we got " + data.nick
- ]
- setTimeout(() => w.chat.send(namsg[Math.floor(Math.random() * namsg.length)]), 250)
- }
- }
- if (msg.startsWith("spg#stats")) {
- let nsqu = Number(data.msg.substring(10))
- if (!isNaN(nsqu) && nsqu >= 0 && nsqu < squaries.length && Math.floor(nsqu) == nsqu) {
- let s = squaries[nsqu]
- setTimeout(() => w.chat.send("Squarie #" + nsqu + ": [Type: " + s.type + " Direction: " + s.dir + " x: " + s.x + " y: " + s.y + " xVel: " + s.vx + " yVel: " + s.vy + " HP: " + Math.round(s.health) + " Dmg: " + Math.round(s.damage) + " K: " + s.kills + "]"), 250)
- } else {
- setTimeout(() => w.chat.send("Error! Squarie #" + nsqu + " does not exist!"), 250)
- }
- }
- if (msg.startsWith("spg#speed")) {
- let val = parseFloat(data.msg.substring(10))
- if (!isNaN(val) && val > 0 && val <= 10) {
- speedMultiplier = val
- setTimeout(() => w.chat.send("Simulation speed set to " + val + "x"), 250)
- } else {
- setTimeout(() => w.chat.send("Invalid speed! Use a number between 0.1 and 10."), 250)
- }
- }
- if (msg.startsWith("spg#quit")) {
- running = false
- setTimeout(() => w.chat.send("Simulation stopped."), 250)
- }
- if (msg.startsWith("spg#help")) {
- let helpMsg = [
- "Available commands:",
- "spg#addsquarie [name] - Add a squarie to the simulation",
- "spg#stats [index] - Get stats for a specific squarie",
- "spg#speed [value] - Set simulation speed (0.1 to 10)",
- "spg#quit - Stop the simulation",
- "spg#help - Show this help message",
- "spg#scores - Show squarie damage and kills"
- ]
- w.chat.send(helpMsg.join("\n"))
- }
- if (msg.startsWith("spg#scores")) {
- let scoreList = squaries.map((s, i) =>
- `S${i}: HP:${Math.round(s.health)} Dmg:${Math.round(s.damage)} K:${s.kills}`
- ).join("\n")
- w.chat.send(scoreList)
- }
- })
- }
Advertisement
Add Comment
Please, Sign In to add comment