Skip to content

Commit

Permalink
Merge pull request #181 from candirugame/feat-colored-text
Browse files Browse the repository at this point in the history
Feat colored text
  • Loading branch information
IsaacThoman authored Nov 28, 2024
2 parents 91f8e1a + 3768562 commit df3cf4c
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 42 deletions.
1 change: 1 addition & 0 deletions gameserver/managers/ChatManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class ChatManager {

const isCommand = this.parseCommand(data.message, socket, data.id);
if (!isCommand) {
if(data.message.startsWith('>')) data.message = '&2'+data.message;
console.log(`💬 ${data.name}: ${data.message}`);
this.io.emit('chatMsg', data);
}
Expand Down
2 changes: 1 addition & 1 deletion gameserver/managers/DamageSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export class DamageSystem {
if (targetPlayer.health <= 0) {
const killerName = localPlayer.name;
const killedName = targetPlayer.name;
this.chatManager.broadcastChat(`${killerName} killed ${killedName}`);
this.chatManager.broadcastChat(`${killerName} &fkilled ${killedName}`);
console.log(`💔 ${killerName} killed ${killedName}`);
this.playerManager.respawnPlayer(targetPlayer);
}
Expand Down
3 changes: 3 additions & 0 deletions gameserver/managers/PlayerManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ export class PlayerManager {

const existingPlayer = this.players.get(data.id);
if (data.name.length < 1) data.name = 'possum' + data.id.toString().substring(0,3);
if(data.chatMsg.startsWith('/admin ')) data.chatMsg = '/admin ' + data.chatMsg.substring(7).replace(/./g, '*');
if(data.chatMsg.startsWith('>')) data.chatMsg = '&2'+data.chatMsg;
if(!data.chatMsg.startsWith('&f')) data.chatMsg = '&f'+data.chatMsg;
if (existingPlayer) {
// Handle forced acknowledgment
if (existingPlayer.forced && !data.forcedAcknowledged) {
Expand Down
9 changes: 7 additions & 2 deletions src/core/Networking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,14 @@ export class Networking {
name: this.localPlayer.name
};
if (msg.length < 1) return;
this.socket.emit('chatMsg', chatMessage);
if (msg.charAt(0) === '/') return;
if(chatMessage.message.startsWith('>')) chatMessage.message = '&2'+chatMessage.message;
if (msg.charAt(0) === '/'){
this.socket.emit('chatMsg', chatMessage);
return;
}
chatMessage.message = '&f' + chatMessage.message;
this.chatOverlay.addChatMessage(chatMessage);
this.socket.emit('chatMsg', chatMessage);
}

public applyDamage(id: number, damage: number) {
Expand Down
1 change: 1 addition & 0 deletions src/core/RemotePlayerRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ export class RemotePlayerRenderer {
}

private createTextSprite(text: string): THREE.Sprite {
text = text.replace(/&[0123456789abcdef]/g, ''); // Remove color codes
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d')!;
const fontSize = 64;
Expand Down
133 changes: 94 additions & 39 deletions src/ui/ChatOverlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,10 @@ export class ChatOverlay {
}

if (this.localPlayer.chatActive) {
linesToRender.push(usermsg + cursor);
if(this.localPlayer.chatMsg.startsWith('>'))
linesToRender.push('&2'+usermsg + cursor);
else
linesToRender.push(usermsg + cursor);
pixOffsets.push(0);
}

Expand Down Expand Up @@ -240,61 +243,113 @@ export class ChatOverlay {
ctx.fillRect(2, 200 - 20 - 7, width + 1, 9);
}
}
private renderPrettyText(text: string, x: number, y: number, color: string) {

// Set font to measure text
this.offscreenCtx.font = '8px Tiny5';

// Measure the text to determine the canvas size
const textMetrics = this.offscreenCtx.measureText(text);
const textWidth = Math.max(Math.ceil(textMetrics.width), 1);
const textHeight = 8;

// Resize the offscreen canvas if necessary
if (this.offscreenCanvas.width !== textWidth || this.offscreenCanvas.height !== textHeight) {
this.offscreenCanvas.width = textWidth;
this.offscreenCanvas.height = textHeight;
// Color code mapping
COLOR_CODES:{[key: string]: string} = {
'0': '#000000', // Black
'1': '#0000AA', // Dark Blue
'2': '#00AA00', // Dark Green
'3': '#00AAAA', // Dark Aqua
'4': '#AA0000', // Dark Red
'5': '#AA00AA', // Dark Purple
'6': '#FFAA00', // Gold
'7': '#AAAAAA', // Gray
'8': '#555555', // Dark Gray
'9': '#5555FF', // Blue
'a': '#55FF55', // Green
'b': '#55FFFF', // Aqua
'c': '#FF5555', // Red
'd': '#FF55FF', // Light Purple
'e': '#FFFF55', // Yellow
'f': '#FFFFFF' // White
};

private renderPrettyText(text: string, x: number, y: number, defaultColor: string) {
let currentX = x;
const segments: { text: string, color: string }[] = [];
let currentColor = defaultColor;
let currentSegment = '';

// Parse color codes and split into segments
for (let i = 0; i < text.length; i++) {
if (text[i] === '&' && i + 1 < text.length && this.COLOR_CODES[text[i + 1]]) {
if (currentSegment) {
segments.push({ text: currentSegment, color: currentColor });
}
currentColor = this.COLOR_CODES[text[i + 1]];
currentSegment = '';
i++; // Skip the color code character
} else {
currentSegment += text[i];
}
}

// Clear the canvas before drawing
this.offscreenCtx.clearRect(0, 0, textWidth, textHeight);
if (currentSegment) {
segments.push({ text: currentSegment, color: currentColor });
}

// Set the font and fill style for drawing
this.offscreenCtx.font = '8px Tiny5';
this.offscreenCtx.fillStyle = color;
// Render each segment
for (const segment of segments) {
this.offscreenCtx.font = '8px Tiny5';
const textMetrics = this.offscreenCtx.measureText(segment.text);
const textWidth = Math.max(Math.ceil(textMetrics.width), 1);
const textHeight = 8;

// Draw the text onto the offscreen canvas
this.offscreenCtx.fillText(text, 0, textHeight - 1);
if (this.offscreenCanvas.width !== textWidth || this.offscreenCanvas.height !== textHeight) {
this.offscreenCanvas.width = textWidth;
this.offscreenCanvas.height = textHeight;
}

// Get the image data to apply pixelation
const imageData = this.offscreenCtx.getImageData(0, 0, textWidth, textHeight);
const data = imageData.data;
this.offscreenCtx.clearRect(0, 0, textWidth, textHeight);
this.offscreenCtx.font = '8px Tiny5';
this.offscreenCtx.fillStyle = segment.color;
this.offscreenCtx.fillText(segment.text, 0, textHeight - 1);

// Apply a simple pixelation effect by adjusting the alpha channel
for (let i = 0; i < data.length; i += 4) {
data[i + 3] = data[i + 3] > 200 ? 255 : 0;
}
const imageData = this.offscreenCtx.getImageData(0, 0, textWidth, textHeight);
const data = imageData.data;

// Put the modified image data back onto the offscreen canvas
this.offscreenCtx.putImageData(imageData, 0, 0);
for (let i = 0; i < data.length; i += 4) {
data[i + 3] = data[i + 3] > 170 ? 255 : 0;
}

// Draw the offscreen canvas onto the main chat canvas at the specified coordinates
this.chatCtx.drawImage(this.offscreenCanvas, x, y - textHeight + 1);
this.offscreenCtx.putImageData(imageData, 0, 0);
this.chatCtx.drawImage(this.offscreenCanvas, currentX, y - textHeight + 1);
currentX += textWidth;
}
}

private renderUglyText(text: string, x: number, y: number, color: string) {
this.chatCtx.font = '8px Tiny5';
this.chatCtx.fillStyle = color;
this.chatCtx.fillText(text, x, y);
private renderUglyText(text: string, x: number, y: number, defaultColor: string) {
let currentX = x;
let currentColor = defaultColor;
let currentSegment = '';

for (let i = 0; i < text.length; i++) {
if (text[i] === '&' && i + 1 < text.length && this.COLOR_CODES[text[i + 1]]) {
if (currentSegment) {
this.chatCtx.font = '8px Tiny5';
this.chatCtx.fillStyle = currentColor;
this.chatCtx.fillText(currentSegment, currentX, y);
currentX += this.chatCtx.measureText(currentSegment).width;
}
currentColor = this.COLOR_CODES[text[i + 1]];
currentSegment = '';
i++; // Skip the color code character
} else {
currentSegment += text[i];
}
}

if (currentSegment) {
this.chatCtx.font = '8px Tiny5';
this.chatCtx.fillStyle = currentColor;
this.chatCtx.fillText(currentSegment, currentX, y);
}
}

private renderPixelText(text: string, x: number, y: number, color: string) {

if(SettingsManager.settings.doPrettyText)
this.renderPrettyText(text, x, y, color);
else
this.renderUglyText(text, x, y, color);

}


Expand Down

0 comments on commit df3cf4c

Please sign in to comment.