Skip to content

Instantly share code, notes, and snippets.

@jlouis
Created January 21, 2011 23:28
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jlouis/790638 to your computer and use it in GitHub Desktop.
Save jlouis/790638 to your computer and use it in GitHub Desktop.
RPG/MMORPG/MUD Item handling ideas
-module(item).
-export([gen_shield/0]).
-export([transmogrify/2, as_item/1]).
-export([weapon_damage/1, look/1]).
-record(item, {
%% Rather arbitrary identity
id :: term(),
%% Proplist of items properties
properties :: [{atom(), term()}]}).
gen_shield() ->
Desc = "A spiked and very sturdy looking tower shield",
Damage = {6,d,6},
ArmorRating = 16,
#item { id = {shield, 37},
properties = [{as_weapon, Damage},
{description, Desc},
{as_armor, ArmorRating}]}.
%% This is a neat trick in a functional language. The representation of the
%% item at hand can change view depending on who needs to look at
%% it. This way, transmogrifying the object into something else makes
%% it suitable to use when viewed in a specific way.
%%
%% If we don our weapon-eyeglasses, then it is a weapon all of a sudden:
transmogrify(Ty, #item { id = Id, properties = Props } = I) ->
%% This can also be a call directly to a submodule:
%% Ty:create(Id, Props)
case Ty of
weapon ->
{weapon, Id, I,
proplist:get_value(description, Props),
proplist:get_value(as_weapon, Props)};
armor ->
{armor, Id, I,
proplist:get_value(description, Props),
proplist:get_value(as_armor, Props)}
end.
%% Of course, there is a way to bring back the general view
as_item({weapon, I, _, _}) -> I;
as_item({armor, I, _, _}) -> I.
%% This should reside in a weapon:damage function inside the weapon module
%% in a real solution
weapon_damage({weapon, _Id, _Desc, Damage}) -> Damage.
%% Generic, polymorphic, function to look at an object.
look(#item { properties = Ps }) ->
proplists:get_value(description, Ps);
look({weapon, _, Desc, _}) -> Desc;
look({armor , _, Desc, _}) -> Desc;
%% Not specific? Look up the module that knows how to act on it and
%% call it
look(Tup) when is_tuple(Tup) ->
Ty = element(1, Tup),
Ty:look(Tup).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment