1 import std
.container
.rbtree
: set
= redBlackTree
;
3 import BearLibTerminal
;
19 abstract class Being
{
23 int xp
, hp
= 30, maxhp
, mp
, maxmp
;
25 RGBColour fgcolour
, bgcolour
;
28 private struct _attr
{ bool reverse
, italic
, bold
, underline
; }
31 pragma(inline
, true) {
32 pure void inchp(int amount
=1) {
33 if ((amount
+ hp
) > maxhp
) {
42 pure bool isfemale() {
51 override Action
getaction() {
52 import std
.random
: uniform
;
53 return uniform(Action
.MoveNorth
, Action
.MoveSouthRight
);
56 fgcolour
= RGBColour(0x00ff00);
57 bgcolour
= RGBColour(0xff00ff);
66 fgcolour
= RGBColour(0xffffff);
67 bgcolour
= RGBColour(0x000000);
71 this.glyph
= Glyph
.at
;
73 override Action
getaction() {
75 // TODO gdc doesn't like RedBlackTrees. But someday it will
77 //static immutable bool[int] vikeys = ['h': 1, 'j': 1, 'k': 1, 'l': 1, 'y': 1, 'u': 1, 'b': 1, 'n': 1, 'q': 1, '.', 'w': 1];
78 bool[dchar] vikeys
= ['h': 1, 'j': 1, 'k': 1, 'l': 1, 'y': 1, 'u': 1, 'b': 1, 'n': 1, 'q': 1, '.': 1, 'w': 1];
80 static immutable auto vikeys
= set
!dchar('h', 'j', 'k', 'l', 'y', 'u', 'b', 'n', 'q', '.', 'w');
86 while ((c
= graphics
.getch()) !in vikeys
) {}
90 tmp
= Action
.MoveLeft
;
93 tmp
= Action
.MoveRight
;
96 tmp
= Action
.MoveSouth
;
99 tmp
= Action
.MoveNorth
;
102 tmp
= Action
.MoveNorthLeft
;
105 tmp
= Action
.MoveNorthRight
;
108 tmp
= Action
.MoveSouthLeft
;
111 tmp
= Action
.MoveSouthRight
;
119 case 'w': // (w)here am I?
120 tmp
= Action
.Printloc
;
139 this(string
[] args
) {
140 graphics
= new Default_chargfx
!BLT0(this);
142 this.map
= genmap(MapType
.caves
);
144 mons
= [u
= new You(graphics
)];
150 map
.for_all((ref Tile x
) => x
.setdefglyph());
154 // If we didn't have this, then if (0, 0) was walkable, then you would automatically get placed there
155 foreach (ref m
; mons
) {
157 m
.loc
.x
= rn1(map_x
+1);
158 m
.loc
.y
= rn1(map_y
+1);
159 } while ((!map
[m
.loc
].walkable
) ||
!mon_at(m
.loc
));
166 void parseargs(string
[] args
) {
167 if (args
.length
== 2) {
168 if (args
[1] == "dumpmap") {
171 } else if (args
[1] == "dumphtmlmap") {
178 // Name credit to lrogue
179 ref Being
mon_at(uint y
, uint x
) {
180 foreach (ref tmpmon
; mons
) {
181 if ((tmpmon
.loc
.y
== y
) && (tmpmon
.loc
.x
== x
)) {
185 // Evil hackery so we can return null
186 static Being tmp
= null;
189 ref Being
mon_at(Vector2n loc
) {
190 return mon_at(loc
.y
, loc
.x
);
196 foreach (row
; map
.get_tiles
) {
197 foreach (tile
; row
) {
198 write(cast(dchar)tile
.glyph
);
207 <html lang="rl"> <!-- RogueLike! -->
209 <meta charset="utf-8">
210 <title>SmuglerRL HTML dump!</title>
212 <body fgcolor="#ffffff" bgcolor="#000000">
213 <div style="font-family: monospace">`);
215 bool clr_changed
, bgclr_changed
;
216 RGBColour fg
, last_fg
, bg
, last_bg
;
217 foreach (row
; map
.get_tiles
) {
218 foreach (tile
; row
) {
228 bgclr_changed
= true;
230 bgclr_changed
= false;
233 if (clr_changed
) write(`</font>`);
234 if (bgclr_changed
) write(`</font>`);
236 with (fg
) writef(`<font color="#%02x%02x%02x">`, r
, g
, b
);
240 with (bg
) writef(`<font bgcolor="#%02x%02x%02x">`, r
, g
, b
);
243 write(cast(dchar)tile
.glyph
);
255 pragma(inline
, true) void refresh() {
258 pragma(inline
, true) void pline(T
...)(T args
) {
259 graphics
.pline(args
);
268 void handlemove(int yshift
, int xshift
, ref Being b
) {
269 if (/*map[b.loc.y+yshift, b.loc.x+xshift].walkable && */!mon_at(b
.loc
.y
+yshift
, b
.loc
.x
+xshift
)) {
270 map
[b
.loc
.y
, b
.loc
.x
].setdefglyph();
271 b
.loc
.y
= b
.loc
.y
+ yshift
;
272 b
.loc
.x
= b
.loc
.x
+ xshift
;
273 // pline("another message, of exceeding length. You should eat it, if you feel like, but make sure it's still long enough. Ugh, it has to be *LONGER*?? FINE>>>");
275 // only when *you* walk into a wall
276 if (cast(You
)b
) pline("there is a thingy there!");
279 outerloop
: while (true) { refresh(); foreach (ref Being mon
; mons
) {
280 act
= mon
.getaction();
281 // If we're moving, then move!
282 if ((Action
.MoveNorth
<= act
) && (act
<= Action
.MoveSouthRight
)) {
288 case Action
.MoveNorth
:
291 case Action
.MoveSouth
:
295 case Action
.MoveLeft
:
298 case Action
.MoveRight
:
301 case Action
.MoveNorthLeft
:
302 deltay
= deltax
= -1;
304 case Action
.MoveNorthRight
:
308 case Action
.MoveSouthLeft
:
312 case Action
.MoveSouthRight
:
319 case Action
.Printloc
:
320 pline("(%s, %s)", mon
.loc
.x
, mon
.loc
.y
);
327 handlemove(deltay
, deltax
, mon
);
329 if (cast(You
)mon
) { refresh(); }
334 do_fov(map
, u
.loc
.x
, u
.loc
.y
, 100, true);