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", "Armor1", 118),
49 ActorDefD2D("item", "Armor2", 119),
50 ActorDefD2D("item", "MegaSphere", 120),
51 ActorDefD2D("item", "Invulnerability", 121),
52 ActorDefD2D("item", "Aqualung", 122),
53 ActorDefD2D("item", "RedKey", 123),
54 ActorDefD2D("item", "GreenKey", 124),
55 ActorDefD2D("item", "BlueKey", 125),
56 ActorDefD2D("item", "ProtectionSuit", 126),
57 ActorDefD2D("item", "Super", 127),
58 ActorDefD2D("item", "RedTorch", 128),
59 ActorDefD2D("item", "GreenTorch", 129),
60 ActorDefD2D("item", "BlueTorch", 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
;
121 __gshared ImgSprite
[uint] allSprites
; // to avoid loading sprites twice they are keyed by namestrid
122 ImgSprite
*[][][uint] animSprites
;
123 //__gshared ImgSprite*[][] animCur;
125 // load actor graphics
126 void loadGraphics () {
127 //conwriteln("loading graphics for '", fullname, "'; anims.length=", anims.length, "; allSprites.length=", allSprites.length);
128 if (anims
.length
== 0) return; // no graphics here
129 //if (allSprites.length > 0) return;
131 foreach (auto anma2
; anims
.byValue
) {
132 foreach (auto anma
; anma2
) {
133 foreach (StrId ssid
; anma
) {
134 //conwriteln(fullname, ": ssid=", ssid.id, "; is ", ssid.get);
135 ImgSprite
* spi
= null;
137 spi
= ssid
.id
in allSprites
;
139 //conwriteln("loading sprite '", ssid.get, "'");
140 D2DImage vga
= new D2DImage(ssid
.get
);
141 allSprites
[ssid
.id
] = ImgSprite();
142 spi
= ssid
.id
in allSprites
;
143 assert(spi
!is null);
145 spi
.tex
= new Texture(spi
.vga
.asTCImage
, Texture
.Option
.Nearest
);
147 //conwriteln("cached sprite '", ssid.get, "'");
153 // now fill animSprites
154 foreach (auto anma2
; anims
.byKeyValue
) {
155 if (anma2
.key
!in animSprites
) animSprites
[anma2
.key
] = new ImgSprite
*[][](2); // 2 dirs
156 auto aspx
= animSprites
[anma2
.key
];
157 foreach (immutable dir
, auto anma
; anma2
.value
) {
158 foreach (StrId ssid
; anma
) {
159 ImgSprite
* spi
= null;
160 if (ssid
.id
!= 0) spi
= ssid
.id
in allSprites
;
167 // unload actor graphics
168 void releaseGraphics () {
170 //allSprites.clear();
173 int nextAnimIdx (StrId state
, uint dir
, int curidx
) {
174 if (dir
!= 0) dir
= 1;
175 if (++curidx
<= 0) return 0;
176 if (auto spra
= state
.id
in animSprites
) {
177 if (curidx
< (*spra
).ptr
[dir
].length
) return curidx
;
183 ImgSprite
* animSpr (StrId state
, uint dir
, int curidx
) {
184 if (dir
!= 0) dir
= 1;
185 if (curidx
< 0) return null;
186 if (auto spra
= state
.id
in animSprites
) {
187 if (curidx
>= (*spra
).ptr
[dir
].length
) return null;
188 return (*spra
).ptr
[dir
].ptr
[curidx
];
193 private __gshared
uint nextId
= 1;
195 this (string ctype
, string cname
) {
198 fullname
= classtype
~":"~classname
;
202 void clearAllFrames (StrId state
) {
206 void clearFrames (StrId state
) {
207 anims
.remove(state
.id
);
210 void addFrame (StrId state
, uint dir
, StrId sprname
) {
211 //conwriteln("new frame for '", fullname, "'; state=", state.get, "; sprname=", sprname.get, "; dir=", dir);
212 if (dir
> 1) throw new Exception("addFrame: invalid dir");
213 if (state
.id
!in anims
) anims
[state
.id
] = new StrId
[][](2);
214 auto aa
= anims
[state
.id
];
218 void setAnimInitFunc (FuncPool
.FuncInfo fi
) {
219 if (fi
is null) return;
220 if (fi
.mgtype
!= ":void") throw new Exception("invalid actor animation init function");
224 void setInitFunc (FuncPool
.FuncInfo fi
) {
225 if (fi
is null) return;
226 if (fi
.mgtype
!= ":void:Actor") throw new Exception("invalid actor init function");
230 void setThinkFunc (FuncPool
.FuncInfo fi
) {
231 if (fi
is null) return;
232 if (fi
.mgtype
!= ":void:Actor") throw new Exception("invalid actor think function");
236 void callAnimInit (DACSVM vm
) {
237 foreach (auto fi
; fiAnimInit
) {
243 void callInit (DACSVM vm
, ActorId aid
) {
244 if (fiInit
is null ||
!aid
.valid
) return;
246 vm
.pushUint(aid
.id
); // arg0
247 vm
.executeFunc(fiInit
);
250 void callThink (DACSVM vm
, ActorId aid
) {
251 if (fiThink
is null ||
!aid
.valid
) return;
253 vm
.pushUint(aid
.id
); // arg0
254 vm
.executeFunc(fiThink
);
259 // ////////////////////////////////////////////////////////////////////////// //
260 public __gshared ActorDef
[string
] actordefs
; // by fullname
263 public ActorDef
findD2DActorDef (ushort mapid
) {
264 if (mapid
== 0) assert(0);
265 if (auto dad
= mapid
in d2dactordefsById
) {
266 auto adef
= findActorDefByFullName(dad
.fullname
);
267 if (adef
is null) throw new Exception("can't find DACS actor definition for D2D actor '"~dad
.fullname
~"'");
270 import std
.conv
: to
;
271 throw new Exception("can't find D2D ActorDef for mapid "~to
!string(mapid
));
275 public ActorDef
findActorDefByFullName (const(char)[] fullname
) {
276 if (auto fd
= fullname
in actordefs
) return *fd
;
281 public ActorDef
findActorDef (const(char)[] ctype
, const(char)[] cname
) {
282 if (ctype
.length
+cname
.length
> 1024) assert(0);
284 buf
[0..ctype
.length
] = ctype
[];
285 buf
[ctype
.length
] = ':';
286 buf
[ctype
.length
+1..ctype
.length
+1+cname
.length
] = cname
[];
287 if (auto fd
= buf
[0..ctype
.length
+1+cname
.length
] in actordefs
) return *fd
;
292 public ActorDef
findActorDef (StrId ctype
, StrId cname
) { return findActorDef(ctype
.get
, cname
.get
); }
295 public ActorDef
registerActorDef (string classtype
, string classname
) {
296 string fullname
= classtype
~":"~classname
;
297 if (fullname
!in actordefs
) actordefs
[fullname
] = new ActorDef(classtype
, classname
);
298 if (auto fd
= fullname
in actordefs
) return *fd
;