script: marked all unsafe pointer operations with `cast([unsafe])`
[k8vavoom.git] / progs / common / linespec / entityex / EntityEx.LineAttack.Debug.vc
blobf46dc25d351bd6e0d2486c33a94b8e3ef0c444d6
1 //**************************************************************************
2 //**
3 //**    ##   ##    ##    ##   ##   ####     ####   ###     ###
4 //**    ##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5 //**     ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6 //**     ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7 //**      ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8 //**       #    ##    ##    #      ####     ####   ##       ##
9 //**
10 //**  Copyright (C) 1999-2006 Jānis Legzdiņš
11 //**  Copyright (C) 2018-2023 Ketmar Dark
12 //**
13 //**  This program is free software: you can redistribute it and/or modify
14 //**  it under the terms of the GNU General Public License as published by
15 //**  the Free Software Foundation, version 3 of the License ONLY.
16 //**
17 //**  This program is distributed in the hope that it will be useful,
18 //**  but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 //**  GNU General Public License for more details.
21 //**
22 //**  You should have received a copy of the GNU General Public License
23 //**  along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 //**
25 //**************************************************************************
28 //==========================================================================
30 //  DebugCheckMidTex
32 //==========================================================================
33 final void DebugCheckMidTex () {
34   TVec aimDir;
35   //Aim(aimDir, 16.0*64.0, default, /*noAAim*/true);
36   AngleVector(Angles, out aimDir);
38   auto shootOrigin = Origin;
39   shootOrigin.z += CalculateLineAttackZOfs();
41   trsplat_t tr;
42   DebugTraceLineEx(shootOrigin, aimDir, 8192, allowEntities:false, out tr, stopat3dmidtex:true, nozofs:true);
43   // spawn particles
44   if (tr.didhit) {
45     TVec ptorg = tr.hit;
46     //if (!tr.line) ptorg += in.plane.normal*1.0f;
47     int c = P_Random()>>1;
48     foreach (int i; 0..MAXPLAYERS) {
49       if (!Level.Game.Players[i]) continue;
50       if (!Level.Game.Players[i].bSpawned) continue;
51       PlayerEx(Level.Game.Players[i]).ParticleEffect(20, LineSpecialLevelInfo::pt_static,
52                LineSpecialLevelInfo::pt_explode2, ptorg, 0.0, vector(32.0, 32.0, 32.0),
53                0.5, 10.0, 40.0, RGB(c, c, c), 0.8, 0.0);
54     }
55   }
56   // spawn decal
57   //k8:TODO: this should be strictly client-side
58   if (tr.didhit) {
59     TVec fdorg = tr.hit;
60     if (tr.line && tr.sec) {
61       SpawnDecal(tr.hit, 'K8BigScorchTestRot', tr.side, tr.line);
62       fdorg += tr.line.normal*2.0; // move slightly away from the wall
63     }
64     SpawnFlatDecal(fdorg, 'K8BigScorchTest', 2);
65     /*
66     else {
67       XLevel.AddFlatDecal(tr.hit, 'BigScorch', 32);
68     }
69     */
70   }
71   // show some info
72   if (tr.didhit && tr.line) {
73     float top, bot;
74     bool ok = XLevel.GetMidTexturePosition(tr.line, tr.side, out bot, out top);
75     printdebug("DebugCheckMidTex(%B): hitpoint=%s; top=%s; bot=%s; flags=0x%08x", ok, tr.hit, top, bot, (tr.line ? tr.line->flags : 0));
76     if (tr.line) {
77       //tr.line.alpha = 1.0;
78       if (tr.line.frontsector && tr.line.backsector /*&&
79           tr.line.frontsector.floor.normal.z == 1 && tr.line.frontsector.ceiling.normal.z == -1 &&
80           tr.line.backsector.floor.normal.z == 1 && tr.line.backsector.ceiling.normal.z == -1*/)
81       {
82         //printdebug("linedef #%d", tr.line-&XLevel.Lines[0]);
83         float ffz1 = tr.line.frontsector.floor.GetPointZClamped(*tr.line.v1);
84         float ffz2 = tr.line.frontsector.floor.GetPointZClamped(*tr.line.v2);
85         //if (ffz1 != ffz2) Error("OOPS(front floor)");
86         float fcz1 = tr.line.frontsector.ceiling.GetPointZClamped(*tr.line.v1);
87         float fcz2 = tr.line.frontsector.ceiling.GetPointZClamped(*tr.line.v2);
88         //if (fcz1 != fcz2) Error("OOPS(front ceiling)");
89         float bfz1 = tr.line.backsector.floor.GetPointZClamped(*tr.line.v1);
90         float bfz2 = tr.line.backsector.floor.GetPointZClamped(*tr.line.v2);
91         //if (bfz1 != bfz2) Error("OOPS(back floor)");
92         float bcz1 = tr.line.backsector.ceiling.GetPointZClamped(*tr.line.v1);
93         float bcz2 = tr.line.backsector.ceiling.GetPointZClamped(*tr.line.v2);
94         //if (bcz1 != bcz2) Error("OOPS(back ceiling)");
95         printdebug("linedef %d: (f/b secs=%d/%d); ffz=(%f:%f); fcz=(%f:%f); bfz=(%f:%f); bcz=(%f:%f); alpha=%f; special=%s<%s>; arg=(%s,%s,%s,%s,%s)",
96             cast([unsafe])(tr.line-&XLevel.Lines[0]),
97             cast([unsafe])(tr.line.frontsector-&XLevel.Sectors[0]),
98             cast([unsafe])(tr.line.backsector-&XLevel.Sectors[0]),
99             ffz1, ffz2, fcz1, fcz2, bfz1, bfz2, bcz1, bcz2,
100             tr.line.alpha,
101             tr.line.special, LineSpecial2Str(tr.line.special),
102             tr.line.arg1, tr.line.arg2, tr.line.arg3, tr.line.arg4, tr.line.arg5);
103         printdebug("fsec(%d): ceiling=%f; floor=%f",
104                    cast([unsafe])(tr.line.frontsector-&XLevel.Sectors[0]),
105                    tr.line.frontsector.ceiling.minz, tr.line.frontsector.floor.maxz);
106         printdebug("bsec(%d): ceiling=%f; floor=%f",
107                    cast([unsafe])(tr.line.backsector-&XLevel.Sectors[0]),
108                    tr.line.backsector.ceiling.minz, tr.line.backsector.floor.maxz);
109       } else {
110         float ffz1 = tr.line.frontsector.floor.GetPointZClamped(*tr.line.v1);
111         float ffz2 = tr.line.frontsector.floor.GetPointZClamped(*tr.line.v2);
112         //if (ffz1 != ffz2) Error("OOPS(front floor)");
113         float fcz1 = tr.line.frontsector.ceiling.GetPointZClamped(*tr.line.v1);
114         float fcz2 = tr.line.frontsector.ceiling.GetPointZClamped(*tr.line.v2);
115         //if (fcz1 != fcz2) Error("OOPS(front ceiling)");
116         printdebug("linedef %d: (f sec=%d); ffz=(%f:%f); fcz=(%f:%f); special=%s<%s>; arg=(%s,%s,%s,%s,%s)",
117             cast([unsafe])(tr.line-&XLevel.Lines[0]),
118             cast([unsafe])(tr.line.frontsector-&XLevel.Sectors[0]),
119             ffz1, ffz2, fcz1, fcz2,
120             tr.line.special, LineSpecial2Str(tr.line.special),
121             tr.line.arg1, tr.line.arg2, tr.line.arg3, tr.line.arg4, tr.line.arg5);
122       }
123       foreach (auto snum; 0..2) {
124         if (tr.line.sidenum[snum] < 0) continue;
125         side_t *sd = cast([unsafe])(&XLevel.Sides[tr.line.sidenum[snum]]);
126         printdebug("side %s: toptex(%d)=%s; midtex(%d)=%s; bottex(%d)=%s", snum,
127           sd.TopTexture, GetTextureName(sd.TopTexture),
128           sd.MidTexture, GetTextureName(sd.MidTexture),
129           sd.BottomTexture, GetTextureName(sd.BottomTexture));
130       }
131     }
133     #if 0
134     auto real_hit_point = tr.hit;
135     auto hitPoint = real_hit_point-(4.0*aimDir);
136     // spawn bullet puff
137     SpawnPuff(hitPoint, /*distance*/8192, BulletPuff, none, tr.sec, tr.line, real_hit_point);
138     #endif
139   }
141   /+
142   LineAttack(aimDir, /*Range*/10000, /*damage*/10000,
143     BulletPuff, default, default,
144     default, false);
145   +/
149 //==========================================================================
151 //  DebugTraceLineEx
153 //  Trace line to the wall or entity.
154 //  Returns `true` if wall was hit.
155 //  Returns `false` if floor/ceiling was hit, or nothing was hit.
157 //==========================================================================
158 private final bool DebugTraceLineEx (TVec org, TVec dir, float distance, bool allowEntities, optional out trsplat_t tr, optional bool stopat3dmidtex, optional bool nozofs) {
159   TVec shootOrigin = org;
160   if (!nozofs) shootOrigin.z += (bIsPlayer ? PlayerEx(Player).GetAttackZOfs : 8.0);
162   TVec dst = shootOrigin+distance*dir;
164   tr.org = shootOrigin;
165   tr.hit = dst;
166   tr.line = nullptr;
167   tr.sec = nullptr;
168   tr.didhit = false;
169   tr.mobj = none;
171   TVec hitPoint;
172   line_t *li;
173   int side;
174   sector_t *sec;
175   intercept_t in;
177   foreach PathTraverse(out in, shootOrigin, dst, PT_ADDLINES|(allowEntities ? PT_ADDTHINGS : 0)|(Level.CompatTrace ? PT_COMPAT : 0), SPF_NOBLOCKING, ML_BLOCKEVERYTHING) {
178     if (in.bIsAPlane) {
179       if (in.bIsASky) {
180         printdebug("skyplane!");
181       } else {
182         if (in.plane.normal.z > 0.0f) printdebug("floor plane!"); else printdebug("ceiling plane!");
183         #if 0
184         // flat decal test
185         //XLevel.AddFlatDecal(in.hitpoint, 'K8BigScorchTest', 32);
186         XLevel.AddFlatDecal(in.hitpoint, 'BigScorch', 32);
187         #endif
188       }
189       tr.hit = in.hitpoint;
190       tr.didhit = true;
191       return false;
192     }
194     if (in.bIsALine) {
195       li = in.line;
196       hitPoint = in.hitpoint;
197       side = in.side;
198       sec = in.sector;
200       if (!li->pobject && (li->flags&ML_TWOSIDED)) {
201         opening_t *open = XLevel.LineOpenings(li, hitPoint, SPF_NOBLOCKING, stopat3dmidtex);
202         if (open) {
203           printdebug("SKYFLAT: %d (%s)", Level.Game.skyflatnum, GetTextureName(Level.Game.skyflatnum));
204           printdebug(":: line #%d (flags=0x%08x) ::", cast([unsafe])(li-&XLevel.Lines[0]), li->flags);
205           foreach (auto snum; 0..2) {
206             if (li.sidenum[snum] < 0) continue;
207             side_t *sd = cast([unsafe])(&XLevel.Sides[li.sidenum[snum]]);
208             printdebug("side %s: toptex(%d)=%s; midtex(%d)=%s; bottex(%d)=%s", snum,
209               sd.TopTexture, GetTextureName(sd.TopTexture),
210               sd.MidTexture, GetTextureName(sd.MidTexture),
211               sd.BottomTexture, GetTextureName(sd.BottomTexture));
212           }
213           for (opening_t *o = open; o; o = o->next) {
214             printdebug(" opening:");
215             printdebug("  open bot: %s", o->bottom);
216             printdebug("  open top: %s", o->top);
217             printdebug("  open range: %s", o->range);
218             printdebug("  open lowfloor: %s", o->lowfloor);
219             printdebug("  open floor: (%s:%s)", o->efloor.spGetNormal(), o->efloor.spGetDist());
220             printdebug("  open ceiling: (%s:%s)", o->eceiling.spGetNormal(), o->eceiling.spGetDist());
221           }
222         }
223         if (stopat3dmidtex && (li->flags&ML_3DMIDTEX)) {
224           // stop right here
225           printdebug("!!!!");
226           in.bIsABlockingLine = true;
227         }
229         if (in.bIsASky) {
230           // it's a sky hack wall
231           printdebug("opening: skyhack!");
232           tr.hit = hitPoint;
233           tr.didhit = true;
234           return false;
235         }
236       }
238       if (!in.bIsABlockingLine) continue;
240       tr.hit = hitPoint;
241       tr.line = li;
242       tr.sec = sec;
243       tr.side = side;
244       tr.didhit = true;
246       // don't go any farther
247       return true;
248     }
250     // thing
251     if (in.Thing == self) continue;
252     hitPoint = in.hitpoint;
253     tr.hit = hitPoint;
254     tr.mobj = in.Thing;
255     return false;
256   }
258   tr.hit = dst;
259   tr.didhit = false;
260   return false;