Skip to content

Commit

Permalink
Merge pull request #31 from oestrich/configure-colors
Browse files Browse the repository at this point in the history
Configure colors
  • Loading branch information
oestrich committed Apr 7, 2018
2 parents a42ab90 + 198f860 commit 41dccca
Show file tree
Hide file tree
Showing 24 changed files with 450 additions and 134 deletions.
2 changes: 2 additions & 0 deletions assets/app/js/app.js
@@ -1,4 +1,6 @@
import "phoenix_html"
import {channel} from "./socket"

window.gameConfig = {};

channel.join()
75 changes: 49 additions & 26 deletions assets/app/js/color.js
@@ -1,6 +1,54 @@
const DEFAULT_COLORS = ["black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"];

let defaultColor = (tag, color) => {
let configuredColor = gameConfig["color_" + tag] || color;
return () => {
return `{${configuredColor}}`;
};
};

export function defaultColorCSS(tag, color) {
let configuredColor = gameConfig["color_" + tag] || color;
if (DEFAULT_COLORS.includes(configuredColor)) {
return configuredColor;
} else {
return `color-code-${configuredColor}`;
}
}

function formatColor(payload) {
let string = payload.message;

string = string.replace(/{npc}/g, defaultColor("npc", "yellow"));
string = string.replace(/{item}/g, defaultColor("item", "cyan"));
string = string.replace(/{player}/g, defaultColor("player", "blue"));
string = string.replace(/{skill}/g, defaultColor("skill", "white"));
string = string.replace(/{quest}/g, defaultColor("quest", "yellow"));
string = string.replace(/{room}/g, defaultColor("room", "green"));
string = string.replace(/{say}/g, defaultColor("say", "green"));
string = string.replace(/{shop}/g, defaultColor("shop", "magenta"));
string = string.replace(/{hint}/g, defaultColor("hint", "cyan"));

string = string.replace(/{exit}/g, () => {
return `<span class='${defaultColorCSS("exit", "white")} command'>`;
});

string = string.replace(/{command click=false}/g, defaultColor("command", "white"));
string = string.replace(/{exit click=false}/g, defaultColor("exit", "white"));

string = string.replace(/{command( send='(.*)')?}/g, (_match, _fullSend, command) => {
let color = defaultColorCSS("command", "white");
if (payload.delink == undefined || payload.delink == false) {
if (command != undefined) {
return `<span class='${color} command' data-command='${command}'>`;
} else {
return `<span class='${color} command'>`;
}
} else {
return `<span class='${color}'>`;
}
});

string = string.replace(/{black}/g, "<span class='black'>")
string = string.replace(/{red}/g, "<span class='red'>")
string = string.replace(/{green}/g, "<span class='green'>")
Expand All @@ -15,29 +63,6 @@ function formatColor(payload) {
string = string.replace(/{map:green}/g, "<span class='map-green'>")
string = string.replace(/{map:grey}/g, "<span class='map-grey'>")
string = string.replace(/{map:light-grey}/g, "<span class='map-light-grey'>")
string = string.replace(/{npc}/g, "<span class='yellow'>")
string = string.replace(/{item}/g, "<span class='cyan'>")
string = string.replace(/{player}/g, "<span class='blue'>")
string = string.replace(/{skill}/g, "<span class='white'>")
string = string.replace(/{quest}/g, "<span class='yellow'>")
string = string.replace(/{room}/g, "<span class='green'>")
string = string.replace(/{say}/g, "<span class='green'>")
string = string.replace(/{exit}/g, "<span class='white command'>")
string = string.replace(/{shop}/g, "<span class='magenta'>")
string = string.replace(/{hint}/g, "<span class='cyan'>")

string = string.replace(/{command click=false}/g, "<span class='white'>");
string = string.replace(/{command( send='(.*)')?}/g, (_match, _fullSend, command) => {
if (payload.delink == undefined || payload.delink == false) {
if (command != undefined) {
return "<span class='white command' data-command='" + command + "'>";
} else {
return "<span class='white command'>";
}
} else {
return "<span class='white'>";
}
});

// assume all other tags are custom colors
string = string.replace(/{([\w:-]+)}/g, (_match, color) => {
Expand All @@ -56,8 +81,6 @@ function formatLines(string) {
return string;
}

function format(payload) {
export function format(payload) {
return formatLines(formatColor(payload));
}

export default format
17 changes: 14 additions & 3 deletions assets/app/js/gmcp.js
@@ -1,7 +1,7 @@
import Sizzle from "sizzle"
import _ from "underscore"

import format from "./color"
import {format, defaultColorCSS} from "./color"

import Notifacations from "./notifications"

Expand Down Expand Up @@ -49,6 +49,13 @@ let characterVitals = (channel, data) => {
movementStat.innerHTML = `${data.move_points}/${data.max_move_points} mv`;
}

/**
* Config.Update module
*/
let configUpdate = (channel, data) => {
window.gameConfig = data;
}

/**
* Mail.New module
*/
Expand Down Expand Up @@ -90,16 +97,19 @@ let renderRoom = (channel, room) => {
exits.append(html)
})

let npcColor = defaultColorCSS("npc", "yellow");
let playerColor = defaultColorCSS("player", "blue");

let characters = _.first(Sizzle(".room-info .characters"))
characters.innerHTML = ""
_.each(room.npcs, (npc) => {
let html = document.createElement('div')
html.innerHTML = `<li class="yellow">${npc.name}</li>`
html.innerHTML = `<li class="${npcColor}">${npc.name}</li>`
_.each(html.children, (li) => { characters.append(li) })
})
_.each(room.players, (player) => {
let html = document.createElement('div')
html.innerHTML = `<li class="blue">${player.name}</li>`
html.innerHTML = `<li class="${playerColor}">${player.name}</li>`
_.each(html.children, (li) => { characters.append(li) })
})
}
Expand Down Expand Up @@ -171,6 +181,7 @@ let gmcp = {
"Channels.Tell": tell,
"Character": character,
"Character.Vitals": characterVitals,
"Config.Update": configUpdate,
"Mail.New": mailNew,
"Room.Heard": roomHeard,
"Room.Info": roomInfo,
Expand Down
2 changes: 1 addition & 1 deletion assets/app/js/panel.js
@@ -1,7 +1,7 @@
import Sizzle from "sizzle"
import _ from "underscore"

import format from "./color"
import {format} from "./color"

let scrollToBottom = (callback) => {
let panel = _.first(Sizzle(".panel"))
Expand Down
2 changes: 1 addition & 1 deletion lib/data/channel.ex
Expand Up @@ -5,7 +5,7 @@ defmodule Data.Channel do

use Data.Schema

alias Game.Color
alias Data.Color

schema "channels" do
field(:name, :string)
Expand Down
54 changes: 54 additions & 0 deletions lib/data/color.ex
@@ -0,0 +1,54 @@
defmodule Data.Color do
@moduledoc """
Static color data
"""

@doc """
Valid color codes
"""
def options() do
[
"black",
"red",
"green",
"yellow",
"blue",
"magenta",
"cyan",
"white"
]
end

@doc """
Valid map color codes
"""
def map_colors() do
[
"blue",
"brown",
"dark-green",
"green",
"grey",
"light-grey"
]
end

@doc """
Color "tags" or semantic colors for things in the game like an NPC
"""
def color_tags() do
[
"npc",
"item",
"player",
"skill",
"quest",
"room",
"say",
"command",
"exit",
"shop",
"hint",
]
end
end
12 changes: 11 additions & 1 deletion lib/data/save.ex
Expand Up @@ -328,11 +328,21 @@ defmodule Data.Save do
def valid_config?(save)

def valid_config?(%{config: config}) do
is_map(config) && keys(config) == [:hints, :pager_size, :prompt, :regen_notifications] &&
is_map(config) && config_keys(config) == [:hints, :pager_size, :prompt, :regen_notifications] &&
is_boolean(config.hints) && is_binary(config.prompt) && is_integer(config.pager_size) &&
is_boolean(config.regen_notifications)
end

defp config_keys(config) do
config
|> keys()
|> Enum.reject(fn color ->
color
|> to_string()
|> String.starts_with?("color")
end)
end

@doc """
Validate channels are correct
Expand Down
45 changes: 42 additions & 3 deletions lib/data/save/config.ex
Expand Up @@ -3,6 +3,9 @@ defmodule Data.Save.Config do
Helpers for the player's configuration
"""

alias Data.Color
alias Game.ColorCodes

@doc """
Determine if a string is a configuration option
"""
Expand All @@ -13,7 +16,7 @@ defmodule Data.Save.Config do
"hints" -> true
"pager_size" -> true
"regen_notifications" -> true
_ -> false
config -> color_config?(config)
end
end

Expand All @@ -25,7 +28,7 @@ defmodule Data.Save.Config do
case to_string(config) do
"prompt" -> true
"pager_size" -> true
_ -> false
config -> color_config?(config)
end
end

Expand All @@ -41,14 +44,50 @@ defmodule Data.Save.Config do
"pager_size" ->
Ecto.Type.cast(:integer, value)

_ ->
config ->
maybe_cast_color(config, value)
end
end

defp maybe_cast_color(config, value) do
case color_config?(config) do
true ->
cast_color(value)

false ->
{:error, :bad_config}
end
end

defp cast_color(value) do
case is_a_color?(value) do
true ->
{:ok, value}

false ->
{:error, :bad_config}
end
end

# NOTE: Eventually move this into the Game directory or get all of the caches living in
# the data layer. This shouldn't really be reaching across boundaries.
defp is_a_color?(value) do
Enum.any?(Color.options(), &(&1 == value)) || Enum.any?(ColorCodes.all(), &(&1.key == value))
end

@doc """
Starting prompt
"""
@spec default_prompt() :: String.t()
def default_prompt(), do: "%h/%Hhp %s/%Ssp %m/%Mmv %xxp"

@doc """
Check if a key is color configuration
"""
def color_config?(key) do
Color.color_tags()
|> Enum.any?(fn tag ->
"color_#{tag}" == to_string(key)
end)
end
end

0 comments on commit 41dccca

Please sign in to comment.