Custom breakable screens?
#1 Posted 31 January 2016 - 02:20 PM
A quick question. In Duke3D there are a lot of breakable (tv) screens. Is there an easy way to add new breakable screen tiles (other than coding an sprite actor that changes when hit by a weapon)?
- Jaap
#2 Posted 31 January 2016 - 03:33 PM
This post has been edited by Mark.: 31 January 2016 - 03:33 PM
#3 Posted 31 January 2016 - 04:01 PM
Jaap, on 31 January 2016 - 02:20 PM, said:
A quick question. In Duke3D there are a lot of breakable (tv) screens. Is there an easy way to add new breakable screen tiles (other than coding an sprite actor that changes when hit by a weapon)?
- Jaap
It is possible without replacing existing screen sprites, but it is fiddly and not perfect. I've attached a demo; (A) just shows how to set the thing up, note switches are invisible (use the 'I' key in 3D mode and you will see them as a transparent greenish colour) - to make them invisible, in 2D mode hover over the switch, press F8, select flags and enter 32848 (32768 + what the flags would normally be, which in this case is 80, or 50 hex).
In (A) you can repetedly flip the displayed texture; in ( B ) this is made to only happen once (using the masterswitch instead of activator) and the hitag of the switch is set to 19 to specify breaking glass sound effect. Problem: texture switches just the once, but the sound effect plays with every kick. Hence ( C ) which uses a helper sector for playing the sound just once and puts an invalid sound number on the switch so as to shut the thing up (0 causes a default sound to play). In practice the help sector would be placed on the other side of the breaking screen.
In ( B ) and ( C ) note the speed sprite set to 12288, this effectively makes the floor rise (and hence display second texture) immediately. You calculate this value as the difference between the floor and ceiling height of the sector, which you can determie in 2D mode by pressing the F7 key.
You can now kick, plus shoot with pistol shotgun and machine gun. And the player can smash it with the use key like I said, not perfect.
RPG/Explosion ? Not detected I'm afraid. You may be able to rig something up to do this - refer SE19, "ceiling falls from explosion" but I never got it to work
TTFN,
Jon
Attached File(s)
-
SMASH-ANYTHING.zip (902bytes)
Number of downloads: 114
This post has been edited by The Mechanic: 31 January 2016 - 04:07 PM
#4 Posted 31 January 2016 - 05:52 PM
It uses a mask wall to display the unbroken texture and a closed door to display the broken texture. SE19 also causes ceiling to fall when explosion detected (though you wont get the breaking glass sound in this case).
Two important things with this setup:
1) The furthest (hidden) wall uses a switch texture. It needs to be placed far enough away so that Duke can't press it but far enough such that it is kickable. Normally these two distances are the same (I think) but the blocking wall has an effect here. The use of a mask wall allows the player to still shoot the far wall that has the switch texture on it.
2) There is a second blocking wall in front of the effect i.e. the blocking wall nearest the player start position (or lowest one of the two blocking walls if you view in Mapster). Why is this ? Well try removing the blocking and then kick - you seem to be magically transported through the other blocking wall !! Wee bug in Eduke (or more likely a bug in original Duke3D that is preserved in Eduke).
Hard work ! Replacing an existing breakable tile is certainly easier, but it's still probably easier than using a custom actor if you are not familiar with CON editing (not particularly difficult, just a bit of a learning curve first).
TTFN,
Jon
PS: I suspect the issue I had previously with SE19 was I was using it in an extremely small sector. This version uses a much larger sector.
------EDIT----
OK, now I'm more awake, here is final version which adds breaking glass when hit by RPG (has accidental advantage of you also get a little debris when RPG hits). Also modified the side wall angles as I forgot to take account Duke could shoot at quite a narrow angle. Right THIRD time = qwality . I left previous version attached in case examining the differences help.
Attached File(s)
-
SMASH-ANYTHING2.zip (520bytes)
Number of downloads: 96 -
SMASH-ANYTHING3.zip (593bytes)
Number of downloads: 103
This post has been edited by The Mechanic: 01 February 2016 - 01:45 AM
#5 Posted 31 January 2016 - 09:05 PM
#6 Posted 31 January 2016 - 09:13 PM
#7 Posted 01 February 2016 - 02:18 AM
Trooper Dan, on 31 January 2016 - 09:05 PM, said:
He-he, I like puzzles though I'd more impressed if I got it right the first time - damn getting old.
It's a testiment to how flexible the system is, even if it was put together in a somewhat ad-hoc manner.
Hendricks266, on 31 January 2016 - 09:13 PM, said:
How about a more general EVENT_WALL since as well as knowing when a wall is hit by weapons, it'd also be handy to know:
* when a wall actually blocks a player - via which CON code could interpret it as the player pushing a wall (example: player pushes side of drinks dispenser causing it to move out the way)
* player presses "use" on a wall (example: you shouldn't have done that to that electricity panel, here, have some health damage).
* wall property changed (cstat or displayed picnum). For example in my CON library I'm detecting things like glass breaking so that I can ensure all panes of glass in a liquid tank break together, or you break a pane of glass in a church and a lot of angry newbeasts spawn. By also notifying that a picnum has changed you could also detect things like monitors breaking.
OK, the last two can be achieved already without an event but it does require CON code continually monitoring wall(s) of a sector which has performance implications.
TTFN,
Jon
#8 Posted 01 February 2016 - 09:39 AM
The Mechanic, on 01 February 2016 - 02:18 AM, said:
The Mechanic, on 01 February 2016 - 02:18 AM, said:
That would need to be an event related to clipping/collision.
The Mechanic, on 01 February 2016 - 02:18 AM, said:
That sounds useful, but there's no need to overload this event with multiple functions, which would be sloppy engineering. I'll look into this.
The Mechanic, on 01 February 2016 - 02:18 AM, said:
EVENT_DAMAGEWALL will cover the example you gave. Right now we're not going to create something that notifies scripts when any structure member they specify changes, and it would be poor practice to create a special version for wall picnum and cstat.
#9 Posted 01 February 2016 - 10:59 AM
Hendricks266, on 01 February 2016 - 09:39 AM, said:
Was just thinking that a more generic something-has-happened-to-a-wall event instead of a specific weapon-has-hit-a-wall and might be of use in future.
Hendricks266, on 01 February 2016 - 09:39 AM, said:
OK, I'll give ya that one Just thinking aloud.
Hendricks266, on 01 February 2016 - 09:39 AM, said:
I was trying to get across detecting "something has changed", not specifically it's cstat, picnum, or whatever, just that _something_ has changed.
Anyhow, even if limited to just detecting weapons then that will still be most useful.
TTFN,
Jon
#10 Posted 01 February 2016 - 11:47 AM
The event EVENT_DAMAGEHPLANE seems interesting, too bad there isn't anything on it in the wiki. I just took a quick look at the code that calls the EVENT_DAMAGEHPLANE. A nice way to make breakable ceiling or floor screens but it could use a EVENT_DAMAGEWALL brother to make breakable screenwalls, bleeding walls and what not. :-)
I dunno what the policy on changes to the eduke code is but I would love to try to add that brother to EVENT_DAMAGEHPLANE (I do have some c and c++ experience).
EDIT: Oh snap that was so damn easy to p.o.c. it took me well about 5 minutes!
- Jaap
This post has been edited by Jaap: 01 February 2016 - 12:18 PM
#11 Posted 01 February 2016 - 01:45 PM
Jaap, on 01 February 2016 - 11:47 AM, said:
Then I'm skeptical that it met all the desired engineering specifications that gave me pause. Patches welcome.
#12 Posted 01 February 2016 - 01:57 PM
Hendricks266, on 01 February 2016 - 01:45 PM, said:
Well I just hacked it together. RETURN contains the wall that was hit, if it is higher than 131072, the wallmask/overpic thing was hit (subtract 131072 to get the id of the wall. set RETURN to -1 to stop prevent the rest of the walldamage code be executed. THISACTOR is the sprite that did the damage.
sector.c change A_DamageWall:
void A_DamageWall(int32_t spr, int32_t dawallnum, const vec3_t *pos, int32_t atwith) { int16_t sn = -1; int32_t j, i, darkestwall; walltype *wal = &wall[dawallnum]; int32_t RETURN_in = dawallnum; if (((wal->cstat&16) || wal->overpicnum == BIGFORCE) && wal->nextsector >= 0) { if (sector[wal->nextsector].floorz > pos->z) { if (sector[wal->nextsector].floorz != sector[wal->nextsector].ceilingz) { RETURN_in += 131072; } } } // NOTE: pass RETURN in the dist argument, too. int32_t ret = VM_OnEventWithBoth(EVENT_DAMAGEWALL, spr, screenpeek, RETURN_in, RETURN_in); if (ret < 0) return; if (wal->overpicnum == MIRROR && wal->pal != 4 && ....
in event_defs.h change the GameEvent_t enum (similar change to con_lang.lua):
... EVENT_DISPLAYACCESS, EVENT_MOVESECTOR, EVENT_MOVEEFFECTORS, #ifdef LUNATIC EVENT_ANIMATEALLSPRITES, #endif EVENT_DAMAGEWALL, MAXEVENTS };
change to gamedef.c EventNames array:
... "EVENT_MOVESECTOR", "EVENT_MOVEEFFECTORS", #ifdef LUNATIC "EVENT_ANIMATEALLSPRITES", #endif "EVENT_DAMAGEWALL", };
Example con code that spawn steam when a wall is hit on the position that was hit. When the wallmask/overpic is hit and the overpicnum is 182 it also spawns steam:
onevent EVENT_DAMAGEWALL { setvarvar GTEMP1 RETURN getactor[THISACTOR].picnum GTEMP2 redefinequote 254 EVENT_DAMAGEWALL THISACTOR %d RETURN %d PICNUM %d qsprintf 254 254 THISACTOR RETURN GTEMP2 echo 254 debug 254 ifvarg RETURN 131072 { subvar RETURN 131072 ifvarn wall[RETURN].overpicnum 182 break // setwall[RETURN].overpicnum W_SCREENBREAK // setvar RETURN -1 } else { setwall[RETURN].picnum 268 } // Spawn steam espawn STEAM getactor[THISACTOR].x x setactor[RETURN].x x getactor[THISACTOR].y y setactor[RETURN].y y getactor[THISACTOR].z z setactor[RETURN].z z getactor[THISACTOR].z z setactor[RETURN].z z updatesectorz x y z sect ifvare sect -1 { updatesector x y sect } setactor[RETURN].sectnum sect // Calculate angle getwall[GTEMP1].x GTEMP2 getwall[GTEMP1].y GTEMP3 getwall[GTEMP1].point2 GTEMP4 getwall[GTEMP4].x MX getwall[GTEMP4].y MY subvarvar GTEMP2 MX subvarvar GTEMP3 MY getangle GTEMP4 GTEMP2 GTEMP3 setactor[RETURN].ang GTEMP4 } endevent
Let me know what you think. I am sure I missed a lot of things (it's just a proof of concept).
This post has been edited by Jaap: 01 February 2016 - 01:59 PM
#13 Posted 03 February 2016 - 12:21 PM
If you put glass on a wall that is on a sloped sector and you shoot the part of the glass that is below the floor height (ignoring the slope on the glass won't break. Instead it is registered as a hit on the wall instead of the mask .
if (((wal->cstat&16) || wal->overpicnum == BIGFORCE) && wal->nextsector >= 0) { [b] if (sector[wal->nextsector].floorz > pos->z)[/b] { if (sector[wal->nextsector].floorz != sector[wal->nextsector].ceilingz)
Anyway, about the wall damage event. Is this a feature that will be added and/or is there anything I can do to help realize it?
This post has been edited by Jaap: 03 February 2016 - 12:22 PM