New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Push simple characters around in notifications and rooms #74

Merged
merged 1 commit into from Aug 29, 2018
Jump to file or symbol
Failed to load files and symbols.
+115 −28
Diff settings

Always

Just for now

View
@@ -11,6 +11,7 @@ defmodule Game.Character do
alias Data.NPC
alias Data.User
alias Game.Character.Simple
alias Game.Character.Via
@typedoc """
@@ -22,6 +23,11 @@ defmodule Game.Character do
"""
@type t :: tuple()
@doc """
Convert a character into a stripped down version
"""
def to_simple(character), do: Simple.from_character(character)
@doc """
Let the target know they are being targeted
"""
@@ -7,6 +7,12 @@ defmodule Game.Character.Simple do
defstruct [:type, :id, :name, extra: %{}]
@doc """
Convert a character into their simple version
"""
def from_character({:npc, npc}), do: {:npc, from_npc(npc)}
def from_character({:user, user}), do: {:user, from_user(user)}
@doc """
Convert a user to the simple version
"""
@@ -16,11 +22,29 @@ defmodule Game.Character.Simple do
id: user.id,
name: user.name,
extra: %{
room_id: user.save.room_id,
flags: user.flags,
level: user.save.level,
race: user.race.name,
class: user.class.name,
}
}
end
@doc """
Convert an NPC to the simple version
"""
def from_npc(npc) do
%__MODULE__{
type: :npc,
id: npc.id,
name: npc.name,
extra: %{
original_id: npc.original_id,
status_line: npc.status_line,
description: npc.description,
is_quest_giver: npc.is_quest_giver,
}
}
end
end
View
@@ -143,7 +143,7 @@ defmodule Game.Command.Look do
end
defp maybe_hint_quest(state, room) do
npc_ids = Enum.map(room.npcs, & &1.original_id)
npc_ids = Enum.map(room.npcs, & &1.extra.original_id)
quest =
state.user
@@ -127,7 +127,7 @@ defmodule Game.Command.Quest do
# find quests that are completed and see if npc in the room
def run({:complete, :any}, state = %{socket: socket, user: user, save: save}) do
{:ok, room} = @environment.look(save.room_id)
npc_ids = Enum.map(room.npcs, & &1.original_id)
npc_ids = Enum.map(room.npcs, & &1.extra.original_id)
user
|> Quest.for()
@@ -191,7 +191,7 @@ defmodule Game.Command.Quest do
room
|> Map.get(:npcs)
|> Enum.find(fn npc ->
npc.original_id == progress.quest.giver_id
npc.extra.original_id == progress.quest.giver_id
end)
case npc do
View
@@ -3,6 +3,7 @@ defmodule Game.Environment do
Look at your surroundings, whether a room or an overworld
"""
alias Game.Character
alias Game.Room
alias Game.Overworld
alias Game.Overworld.Sector
@@ -62,10 +63,12 @@ defmodule Game.Environment do
@spec enter(integer(), Character.t(), atom()) :: :ok
def enter("overworld:" <> overworld_id, character, reason) do
{zone_id, sector} = Overworld.sector_from_overworld_id(overworld_id)
character = Character.to_simple(character)
GenServer.cast(Sector.pid(zone_id, sector), {:enter, overworld_id, character, reason})
end
def enter(id, character, reason) do
character = Character.to_simple(character)
GenServer.cast(Room.pid(id), {:enter, character, reason})
end
@@ -77,10 +80,12 @@ defmodule Game.Environment do
@spec leave(integer(), Character.t(), atom()) :: :ok
def leave("overworld:" <> overworld_id, character, reason) do
{zone_id, sector} = Overworld.sector_from_overworld_id(overworld_id)
character = Character.to_simple(character)
GenServer.cast(Sector.pid(zone_id, sector), {:leave, overworld_id, character, reason})
end
def leave(id, character, reason) do
character = Character.to_simple(character)
GenServer.cast(Room.pid(id), {:leave, character, reason})
end
@@ -90,10 +95,12 @@ defmodule Game.Environment do
@spec notify(integer(), Character.t(), tuple()) :: :ok
def notify("overworld:" <> overworld_id, character, event) do
{zone_id, sector} = Overworld.sector_from_overworld_id(overworld_id)
character = Character.to_simple(character)
GenServer.cast(Sector.pid(zone_id, sector), {:notify, overworld_id, character, event})
end
def notify(id, character, event) do
character = Character.to_simple(character)
GenServer.cast(Room.pid(id), {:notify, character, event})
end
@@ -116,10 +123,12 @@ defmodule Game.Environment do
@spec emote(integer(), pid(), Message.t()) :: :ok
def emote("overworld:" <> overworld_id, sender, message) do
{zone_id, sector} = Overworld.sector_from_overworld_id(overworld_id)
sender = Character.to_simple(sender)
GenServer.cast(Sector.pid(zone_id, sector), {:emote, overworld_id, sender, message})
end
def emote(id, sender, message) do
sender = Character.to_simple(sender)
GenServer.cast(Room.pid(id), {:emote, sender, message})
end
@@ -153,26 +162,30 @@ defmodule Game.Environment do
Drop an item into a room
"""
@spec drop(integer(), Character.t(), Item.t()) :: :ok
def drop("overworld:" <> overworld_id, who, item) do
def drop("overworld:" <> overworld_id, character, item) do
{zone_id, sector} = Overworld.sector_from_overworld_id(overworld_id)
GenServer.cast(Sector.pid(zone_id, sector), {:drop, overworld_id, who, item})
character = Character.to_simple(character)
GenServer.cast(Sector.pid(zone_id, sector), {:drop, overworld_id, character, item})
end
def drop(id, who, item) do
GenServer.cast(Room.pid(id), {:drop, who, item})
def drop(id, character, item) do
character = Character.to_simple(character)
GenServer.cast(Room.pid(id), {:drop, character, item})
end
@doc """
Drop currency into a room
"""
@spec drop_currency(integer(), Character.t(), integer()) :: :ok
def drop_currency("overworld:" <> overworld_id, who, currency) do
def drop_currency("overworld:" <> overworld_id, character, currency) do
{zone_id, sector} = Overworld.sector_from_overworld_id(overworld_id)
GenServer.cast(Sector.pid(zone_id, sector), {:drop_currency, overworld_id, who, currency})
character = Character.to_simple(character)
GenServer.cast(Sector.pid(zone_id, sector), {:drop_currency, overworld_id, character, currency})
end
def drop_currency(id, who, currency) do
GenServer.cast(Room.pid(id), {:drop_currency, who, currency})
def drop_currency(id, character, currency) do
character = Character.to_simple(character)
GenServer.cast(Room.pid(id), {:drop_currency, character, currency})
end
@doc """
@@ -181,10 +194,12 @@ defmodule Game.Environment do
@spec update_character(integer(), tuple()) :: :ok
def update_character("overworld:" <> overworld_id, character) do
{zone_id, sector} = Overworld.sector_from_overworld_id(overworld_id)
character = Character.to_simple(character)
GenServer.cast(Sector.pid(zone_id, sector), {:update_character, overworld_id, character})
end
def update_character(id, character) do
character = Character.to_simple(character)
GenServer.cast(Room.pid(id), {:update_character, character})
end
View
@@ -438,7 +438,7 @@ defmodule Game.Format do
Example:
iex> Game.Format.who_is_here(%{players: [%{name: "Mordred"}], npcs: [%{name: "Arthur", status_line: "[name] is here."}]})
iex> Game.Format.who_is_here(%{players: [%{name: "Mordred"}], npcs: [%{name: "Arthur", extra: %{status_line: "[name] is here."}}]})
"{npc}Arthur{/npc} is here.\\n{player}Mordred{/player} is here."
"""
def who_is_here(room) do
@@ -479,7 +479,9 @@ defmodule Game.Format do
Example:
iex> Game.Format.npcs(%{npcs: [%{name: "Mordred", status_line: "[name] is in the room."}, %{name: "Arthur", status_line: "[name] is here."}]})
iex> mordred = %{name: "Mordred", extra: %{status_line: "[name] is in the room."}}
iex> arthur = %{name: "Arthur", extra: %{status_line: "[name] is here."}}
iex> Game.Format.npcs(%{npcs: [mordred, arthur]})
"{npc}Mordred{/npc} is in the room.\\n{npc}Arthur{/npc} is here."
"""
@spec npcs(Room.t()) :: String.t()
@@ -497,7 +499,7 @@ defmodule Game.Format do
def npc_status(npc) do
context()
|> assign(:name, npc_name_for_status(npc))
|> template(npc.status_line)
|> template(npc.extra.status_line)
end
@doc """
@@ -508,7 +510,7 @@ defmodule Game.Format do
context()
|> assign(:name, npc_name(npc))
|> assign(:status_line, npc_status(npc))
|> template(resources(npc.description))
|> template(resources(npc.extra.description))
end
def maybe_items(room, items) do
@@ -860,7 +862,7 @@ defmodule Game.Format do
def npc_name(npc), do: "{npc}#{npc.name}{/npc}"
def npc_name_for_status(npc) do
case Map.get(npc, :is_quest_giver, false) do
case Map.get(npc.extra, :is_quest_giver, false) do
true -> "#{npc_name(npc)} ({quest}!{/quest})"
false -> npc_name(npc)
end
View
@@ -6,6 +6,7 @@ defmodule Game.Session do
@type t :: pid
alias Data.User
alias Game.Character
alias Game.Session
alias Game.Session.Supervisor
alias Game.World.Master, as: WorldMaster
@@ -70,8 +71,21 @@ defmodule Game.Session do
@spec echo(pid, String.t()) :: :ok
def echo(user = %User{}, message) do
case find_connected_player(user) do
nil -> :ok
%{pid: pid} -> echo(pid, message)
nil ->
:ok
%{pid: pid} ->
echo(pid, message)
end
end
def echo(user = %Character.Simple{type: :user}, message) do
case find_connected_player(user) do
nil ->
:ok
%{pid: pid} ->
echo(pid, message)
end
end
@@ -93,8 +107,21 @@ defmodule Game.Session do
@spec notify(pid, tuple()) :: :ok
def notify(user = %User{}, action) do
case find_connected_player(user) do
nil -> :ok
%{pid: pid} -> notify(pid, action)
nil ->
:ok
%{pid: pid} ->
notify(pid, action)
end
end
def notify(user = %Character.Simple{type: :user}, action) do
case find_connected_player(user) do
nil ->
:ok
%{pid: pid} ->
notify(pid, action)
end
end
@@ -15,10 +15,20 @@ defmodule Game.Command.LookTest do
item = create_item(%{name: "Short Sword", description: "A simple blade", keywords: ["sword"]})
insert_item(item)
bandit = %{
id: 1,
name: "Bandit",
extra: %{
original_id: 1,
description: "bandit description",
status_line: "[name] is here."
},
}
room = %{
items: [Item.instantiate(item)],
npcs: [npc_attributes(%{id: 1, name: "Bandit", description: "bandit description"})],
players: [user_attributes(%{id: 1, name: "Player"})],
npcs: [bandit],
players: [%{id: 1, name: "Player"}],
features: [%{key: "log", short_description: "log", description: "a log"}],
zone: %{id: 10, name: "Zone"}
}
@@ -2,6 +2,7 @@ defmodule Game.Command.QuestTest do
use Data.ModelCase
doctest Game.Command.Quest
alias Game.Character
alias Game.Command.Quest
@socket Test.Networking.Socket
@@ -21,7 +22,7 @@ defmodule Game.Command.QuestTest do
npc = create_npc(%{is_quest_giver: true})
quest = create_quest(npc, %{name: "Into the Dungeon"})
%{npc: npc, quest: quest}
%{npc: Character.Simple.from_npc(npc), quest: quest}
end
test "with no active quests", %{state: state} do
@@ -105,10 +106,11 @@ defmodule Game.Command.QuestTest do
describe "complete a quest" do
setup %{state: state} do
guard = create_npc(%{name: "Guard", is_quest_giver: true})
guard = Map.put(guard, :original_id, guard.id)
quest = create_quest(guard, %{name: "Into the Dungeon", experience: 200, currency: 25})
room = Map.merge(@room._room(), %{
npcs: [Map.put(guard, :original_id, guard.id)],
npcs: [Character.Simple.from_npc(guard)],
})
@room.set_room(room)
@npc.clear_notifies()
@@ -222,10 +224,11 @@ defmodule Game.Command.QuestTest do
describe "completing a quest with a shortcut" do
setup %{state: state} do
guard = create_npc(%{name: "Guard", is_quest_giver: true})
guard = Map.put(guard, :original_id, guard.id)
quest = create_quest(guard, %{name: "Into the Dungeon", experience: 200, currency: 25})
room = Map.merge(@room._room(), %{
npcs: [Map.put(guard, :original_id, guard.id)],
npcs: [Character.Simple.from_npc(guard)],
})
@room.set_room(room)
@npc.clear_notifies()
@@ -76,7 +76,7 @@ defmodule Game.FormatTest do
description: "A hallway",
currency: 100,
players: [%{name: "Player"}],
npcs: [%{name: "Bandit", status_line: "[name] is here."}],
npcs: [%{name: "Bandit", extra: %{status_line: "[name] is here."}}],
exits: [%{direction: "north"}, %{direction: "east"}],
shops: [%{name: "Hole in the Wall"}],
features: [%{key: "log", short_description: "A log"}],
@@ -304,7 +304,7 @@ defmodule Game.FormatTest do
describe "npc status line" do
setup do
npc = %{name: "Guard", is_quest_giver: false, status_line: "[name] is here."}
npc = %{name: "Guard", extra: %{status_line: "[name] is here.", is_quest_giver: false}}
%{npc: npc}
end
@@ -315,7 +315,7 @@ defmodule Game.FormatTest do
end
test "if a quest giver it includes a quest mark", %{npc: npc} do
npc = %{npc | is_quest_giver: true}
npc = %{npc | extra: Map.put(npc.extra, :is_quest_giver, true)}
assert Format.npc_name_for_status(npc) == "{npc}Guard{/npc} ({quest}!{/quest})"
assert Format.npc_status(npc) == "{npc}Guard{/npc} ({quest}!{/quest}) is here."
end
ProTip! Use n and p to navigate between commits in a pull request.