1 module d2dadefs
is aliced
;
10 // ////////////////////////////////////////////////////////////////////////// //
11 // known D2D actors (and pseudoactors)
16 ushort mapid
; // thing id in map
18 this (string ctype
, string cname
, ushort thid
) { classtype
= ctype
; classname
= cname
; fullname
= classtype
~":"~classname
; mapid
= thid
; }
20 string
toString () const {
21 import std
.string
: format
;
22 return "ActorDefD2D(%s, %s, %s)".format(classtype
/*.quote*/, classname
/*.quote*/, mapid
);
26 immutable ActorDefD2D
[$] d2dactordefs
= [
27 ActorDefD2D("playerstart", "Player1", 1),
28 ActorDefD2D("playerstart", "Player2", 2),
29 ActorDefD2D("playerstart", "DMStart", 3),
30 ActorDefD2D("item", "Clip", 100),
31 ActorDefD2D("item", "Shell", 101),
32 ActorDefD2D("item", "Rocket", 102),
33 ActorDefD2D("item", "Cell", 103),
34 ActorDefD2D("item", "Ammo", 104),
35 ActorDefD2D("item", "ShellBox", 105),
36 ActorDefD2D("item", "RocketBox", 106),
37 ActorDefD2D("item", "CellPack", 107),
38 ActorDefD2D("item", "StimPack", 108),
39 ActorDefD2D("item", "MediKit", 109),
40 ActorDefD2D("item", "BackPack", 110),
41 ActorDefD2D("item", "Chainsaw", 111),
42 ActorDefD2D("item", "Shotgun", 112),
43 ActorDefD2D("item", "SuperShotgun", 113),
44 ActorDefD2D("item", "MachineGun", 114),
45 ActorDefD2D("item", "RocketLauncher", 115),
46 ActorDefD2D("item", "Plasmagun", 116),
47 ActorDefD2D("item", "BFG900", 117),
48 ActorDefD2D("item", "ArmorGreen", 118),
49 ActorDefD2D("item", "ArmorBlue", 119),
50 ActorDefD2D("item", "MegaSphere", 120),
51 ActorDefD2D("item", "Invulnerability", 121),
52 ActorDefD2D("item", "Aqualung", 122),
53 ActorDefD2D("item", "KeyRed", 123),
54 ActorDefD2D("item", "KeyGreen", 124),
55 ActorDefD2D("item", "KeyBlue", 125),
56 ActorDefD2D("item", "ProtectionSuit", 126),
57 ActorDefD2D("item", "Super", 127),
58 ActorDefD2D("item", "TorchRed", 128),
59 ActorDefD2D("item", "TorchGreen", 129),
60 ActorDefD2D("item", "TorchBlue", 130),
61 ActorDefD2D("item", "Gor1", 131),
62 ActorDefD2D("item", "FCan", 132),
63 ActorDefD2D("item", "Gun2", 133),
64 ActorDefD2D("monster", "Demon", 200),
65 ActorDefD2D("monster", "Imp", 201),
66 ActorDefD2D("monster", "Zombie", 202),
67 ActorDefD2D("monster", "Sergeant", 203),
68 ActorDefD2D("monster", "Cyberdemon", 204),
69 ActorDefD2D("monster", "Chaingunner", 205),
70 ActorDefD2D("monster", "BaronOfHell", 206),
71 ActorDefD2D("monster", "HellKnight", 207),
72 ActorDefD2D("monster", "Cacodemon", 208),
73 ActorDefD2D("monster", "LostSoul", 209),
74 ActorDefD2D("monster", "PainElemental", 210),
75 ActorDefD2D("monster", "SpiderMastermind", 211),
76 ActorDefD2D("monster", "Arachnotron", 212),
77 ActorDefD2D("monster", "Mancubus", 213),
78 ActorDefD2D("monster", "Revenant", 214),
79 ActorDefD2D("monster", "Archvile", 215),
80 ActorDefD2D("monster", "Fish", 216),
81 ActorDefD2D("monster", "Barrel", 217),
82 ActorDefD2D("monster", "Robot", 218),
83 ActorDefD2D("monster", "Man", 219),
87 public immutable ActorDefD2D
[ushort] d2dactordefsById
;
88 //immutable ActorDefD2D[string] d2dactordefsByTN; // by "type:name"
90 shared static this () {
91 foreach (const ref ActorDefD2D d2da
; d2dactordefs
) {
92 d2dactordefsById
[d2da
.mapid
] = d2da
;
93 //d2dactordefsByTN[d2da.fullname] = d2da;
98 // ////////////////////////////////////////////////////////////////////////// //
99 public struct ImgSprite
{
104 @disable this (this);
108 public final class ActorDef
{
112 uint id
; // actor's unique id
114 // animation sequences for stated; keyed by state strid
115 StrId
[][][uint] anims
; // [statestrid][dir][pos]
117 FuncPool
.FuncInfo
[] fiAnimInit
;
118 FuncPool
.FuncInfo fiInit
;
119 FuncPool
.FuncInfo fiThink
;
120 FuncPool
.FuncInfo fiOnTouch
;
122 __gshared ImgSprite
[uint] allSprites
; // to avoid loading sprites twice they are keyed by namestrid
123 ImgSprite
*[][][uint] animSprites
;
124 //__gshared ImgSprite*[][] animCur;
126 // load actor graphics
127 void loadGraphics () {
128 //conwriteln("loading graphics for '", fullname, "'; anims.length=", anims.length, "; allSprites.length=", allSprites.length);
129 if (anims
.length
== 0) return; // no graphics here
130 //if (allSprites.length > 0) return;
132 foreach (auto anma2
; anims
.byValue
) {
133 foreach (auto anma
; anma2
) {
134 foreach (StrId ssid
; anma
) {
135 //conwriteln(fullname, ": ssid=", ssid.id, "; is ", ssid.get);
136 ImgSprite
* spi
= null;
138 spi
= ssid
.id
in allSprites
;
140 //conwriteln("loading sprite '", ssid.get, "'");
141 D2DImage vga
= new D2DImage(ssid
.get
);
142 allSprites
[ssid
.id
] = ImgSprite();
143 spi
= ssid
.id
in allSprites
;
144 assert(spi
!is null);
146 spi
.tex
= new Texture(spi
.vga
.asTCImage
, Texture
.Option
.Nearest
);
148 //conwriteln("cached sprite '", ssid.get, "'");
154 // now fill animSprites
155 foreach (auto anma2
; anims
.byKeyValue
) {
156 if (anma2
.key
!in animSprites
) animSprites
[anma2
.key
] = new ImgSprite
*[][](2); // 2 dirs
157 auto aspx
= animSprites
[anma2
.key
];
158 foreach (immutable dir
, auto anma
; anma2
.value
) {
159 foreach (StrId ssid
; anma
) {
160 ImgSprite
* spi
= null;
161 if (ssid
.id
!= 0) spi
= ssid
.id
in allSprites
;
168 // unload actor graphics
169 void releaseGraphics () {
171 //allSprites.clear();
174 int nextAnimIdx (StrId state
, uint dir
, int curidx
) {
175 if (dir
!= 0) dir
= 1;
176 if (++curidx
<= 0) return 0;
177 if (auto spra
= state
.id
in animSprites
) {
178 if (curidx
< (*spra
).ptr
[dir
].length
) return curidx
;
184 ImgSprite
* animSpr (StrId state
, uint dir
, int curidx
) {
185 if (dir
!= 0) dir
= 1;
186 if (curidx
< 0) return null;
187 if (auto spra
= state
.id
in animSprites
) {
188 if (curidx
>= (*spra
).ptr
[dir
].length
) return null;
189 return (*spra
).ptr
[dir
].ptr
[curidx
];
194 private __gshared
uint nextId
= 1;
196 this (string ctype
, string cname
) {
199 fullname
= classtype
~":"~classname
;
203 void clearAllFrames (StrId state
) {
207 void clearFrames (StrId state
) {
208 anims
.remove(state
.id
);
211 void addFrame (StrId state
, uint dir
, StrId sprname
) {
212 //conwriteln("new frame for '", fullname, "'; state=", state.get, "; sprname=", sprname.get, "; dir=", dir);
213 if (dir
> 1) throw new Exception("addFrame: invalid dir");
214 if (state
.id
!in anims
) anims
[state
.id
] = new StrId
[][](2);
215 auto aa
= anims
[state
.id
];
219 void setAnimInitFunc (FuncPool
.FuncInfo fi
) {
220 if (fi
is null) return;
221 if (fi
.mgtype
!= ":void") throw new Exception("invalid actor animation init function");
225 void setInitFunc (FuncPool
.FuncInfo fi
) {
226 if (fi
is null) return;
227 if (fi
.mgtype
!= ":void:Actor") throw new Exception("invalid actor init function");
231 void setThinkFunc (FuncPool
.FuncInfo fi
) {
232 if (fi
is null) return;
233 if (fi
.mgtype
!= ":void:Actor") throw new Exception("invalid actor think function");
237 void setOnTouchFunc (FuncPool
.FuncInfo fi
) {
238 if (fi
is null) return;
239 if (fi
.mgtype
!= ":void:Actor:Actor") throw new Exception("invalid actor onTouch function");
243 void callAnimInit () {
244 foreach (auto fi
; fiAnimInit
) if (fi
!is null) fi();
247 void callInit (ActorId aid
) {
248 if (fiInit
is null ||
!aid
.valid
) return;
252 void callThink (ActorId aid
) {
253 if (fiThink
is null ||
!aid
.valid
) return;
257 void callOnTouch (ActorId aid
, ActorId aother
) {
258 if (fiOnTouch
is null ||
!aid
.valid ||
!aother
.valid
) return;
259 fiOnTouch(aid
, aother
);
264 // ////////////////////////////////////////////////////////////////////////// //
265 public __gshared ActorDef
[string
] actordefs
; // by fullname
268 public ActorDef
findD2DActorDef (ushort mapid
) {
269 if (mapid
== 0) assert(0);
270 if (mapid
== 1 || mapid
== 2) return findActorDefByFullName("monster:Player");
271 if (auto dad
= mapid
in d2dactordefsById
) {
272 auto adef
= findActorDefByFullName(dad
.fullname
);
273 if (adef
is null) throw new Exception("can't find DACS actor definition for D2D actor '"~dad
.fullname
~"'");
276 import std
.conv
: to
;
277 throw new Exception("can't find D2D ActorDef for mapid "~to
!string(mapid
));
281 public ActorDef
findActorDefByFullName (const(char)[] fullname
) {
282 if (auto fd
= fullname
in actordefs
) return *fd
;
287 public ActorDef
findActorDef (const(char)[] ctype
, const(char)[] cname
) {
288 if (ctype
.length
+cname
.length
> 1024) assert(0);
290 buf
[0..ctype
.length
] = ctype
[];
291 buf
[ctype
.length
] = ':';
292 buf
[ctype
.length
+1..ctype
.length
+1+cname
.length
] = cname
[];
293 if (auto fd
= buf
[0..ctype
.length
+1+cname
.length
] in actordefs
) return *fd
;
298 public ActorDef
findActorDef (StrId ctype
, StrId cname
) { return findActorDef(ctype
.get
, cname
.get
); }
301 public ActorDef
registerActorDef (string classtype
, string classname
) {
302 string fullname
= classtype
~":"~classname
;
303 if (fullname
!in actordefs
) actordefs
[fullname
] = new ActorDef(classtype
, classname
);
304 if (auto fd
= fullname
in actordefs
) return *fd
;