Self-Aware Map Hack (Anti-Savescumming)
#630 posted by
FODDER on 2021/01/07 14:59:29
BIG discovery here! :D Previously this was thought impossible without rewriting the Quake engine at its core.
So while working my kaizo Quake episode (Quake Guy Must Die) on stream I came across a bug in the Quake engine that is actually a really powerful feature in my eyes. Since in my later maps I wanted to prevent saving and loading from working (or you'd die upon load) and I felt that was a nice thematic touch to a finale.
Anyways, the way you do it is this:
Make a SUB_Null brush entity and these keys:
touch: trigger_push_touch
use: InitTrigger
speed: 100
angles: whatever you want tbh
What I noticed in testing is that the direction it attempts to push you is INCORRECT and NOT updated if you don't save or load prior to encountering it. It only corrects its push angle if you load AFTER its creation (aka the use function of InitTrigger being called).
This now means that you can have a map that is self-aware if you have saved and loaded, and you don't even need to rewrite engine code, which previously, was the only known way of stopping savescumming.
Enjoy everyone! You can use this in so many ways, including have the map punish/confuse the player with every monster being replaced by shamblers, changing the map layout entirely, or just flat out killing them like I plan on using it for. :)
Moving Lightning/laser Hack
Hi I'm back again with another juicy map hack ;) I was recently inspired to make a map inspired by air exchange (a scrapped HL2 chapter whose maps were found in the old 2003 beta leak from before the games release) and in my map I want something like those balls of lightning that move up and down like in one of the later rooms (or at least they're there in "airex mod" which is a fixed and completed version of the maps) but I didnt know how to do it, well now I do and I want to share it since it could be useful for other people too. I'd say it's a bit more complicated then my turret hack from before unfortunately. Basically how you do it is you need 3 info_notnulls, ome to fire the lightning 1 to be the target and 1 to trigger the lightning (since normal triggers can't be used with it directly in this case because if you add a targetname to the lightning one it will mess it up and cause it to not move). The first 2 need to be setup similarly for the most part, more specifically they need to be set up kind of like how func_trains are set up in their spawn function since they will move with func_train stuff. So in both of them put these values:
cnt: 1
movetype: 7
nextthink: 0.1
noise: misc/null.wav
noise1: misc/null.wav
solid: 0
sounds: 0
speed: whatever you want
target: name of some path_corner
think: func_train_fin
In the one that will trigger the lightning just put this:
enemy: edict ID of the lightning notnull
targetname: whatever you want
use: CastLightning
Then in the one that you want to actually fire the lightning change the "solid" to 3 and add these:
enemy: edict ID of the other moving info_notnull
health: 9999999999
maxs: 3 values, put whatever you want but ideally it should pretty small like 4 4 4
mins; the exact same as maxs but negative
size: 2*maxs (I'm not 100% sure if you need to actually set maxs mins and size but in my test map it didnt work correctly unless I did so I'm just going to assume you do)
takedamage: 2
th_pain: CastLghtning
You can play around with the mins maxs and size to change the hitbox size of the notnull (at least I'm pretty sure that's what its doing? That's what I gather from reading some quakec references at least) Note that from my testing if the player touches either of the moving notnulls it will cause a map crash (in quakespasm at least) presumably because the game tries to do some bsp collision stuff because it thinks it's a func_train and has a bmpdel and well, it isnt, so it throws a SOLID_BSP with non BSP model error. So you should make the size small if it will come close to the player so they dont inadvertently wind up hitting it.
With the entities themselves set up now you need to set up the paths. This is pretty normal and you need to take into account the normal func_train stuff, with the exception being that the notnull that will fire the lightning needs to have its path 40 units below the other one, because CastLightning raises the entities origin by 40 before casting the lightning because it was made for the shambler.
After the paths are set up then just set up some trigger that targets the notnull that will fire at the one that is moving and make sure it repeats at a constant rate like 60fps for example, if everything is set up correctly you should see lightning arcing between the 2 points as they move from one point on the path to another, you can do a lot of stuff with this like making the vertical moving lightning balls I mentioned at the start or make rotating lines of lightning or make a half life like func_laser, there are lots of possibilities :)
I posted a little demo map in the quake mapping discord if anyone is interested in seeing it in action
@aberrant
Hm my rotating turret hack uses ai_face in its use function with no issue, it's how it rotates to face the player. What could you be doing that would cause it to not work? What is your setup?
Monster Activated Triggers
#635 posted by
Preach on 2021/03/29 17:12:08
Had a brainwave recently, and cracked one of those oft-requested hacks: a trigger which also activates when monsters touch it. And it took less than 25 years to get there!
https://tomeofpreach.wordpress.com/2021/03/29/monster-activated-trigger/
There might be some follow-ups to this article, for instance creating a setup which triggers for monsters but NOT players. I can see a way of doing it but it's inelegant, and I'm hoping with a bit more thought I can replace or refine it.
Did Anyone Get #630 To Work?
A few weeks ago I played around with #630. Couldn't get it to work...
Nothing happened. Saved, loaded just fine.
Today I started from scratch, gave it another try. Same result.
Was anyone successful? If so, what did you do?
#638 posted by
Tribal on 2021/07/11 14:02:47
I don't know if this is the right place to ask, but i have some questions about parms (specifically "SetNewParms" from client.qc)...
In my mod you start the game with a flashlight. It will consumes armor energy if you turn it on, so i give the player the green armor with 50 points of energy when he starts a map:
On SetNewParms i made these changes:
parm1 = IT_SHOTGUN | IT_AXE| IT_LANTERN| IT_ARMOR1; //it_lantern is the flashlight and it_armor1 is the green armor
parm3 = 50; //this is the armor points/value
parm9 = self.armortype = 0.3; //this is the green armor type
(I also made some changes on the "SetChangeParms" code, but that doesn't matter here because the problem is with the SetNewParms code)
My code works perfectly when i load start.bsp, but today i played "Escape from Quakertraz", a custom map that has its own start map called "efq_start.bsp". The map refused to load and the console gave me this:
Address 28(self)entity 0 174(armortype).armortype 4341(?)
client.qc: SetNewParms
(no function)
assignment to world entity
So i made an exception on my "SetNewParms" for this map (changing parm9 back to 0 again, like it was in the original code):
if (world.model == "maps/efq_start.bsp")
parm9 = 0;
And now i can load the map perfectly...
My questions are:
1- Why is this map having a problem with "SetNewParms" if this code is supposed to be called only by the original "start.bsp" and not by some custom start map with another name? :P
2-Why the original start.bsp works fine with "parm9 = self.armortype = 0.3" and this custom map only works with "parm9 = 0"??
It makes no sense to me!
Tribal:
#639 posted by
metlslime on 2021/07/12 18:37:29
So, the best place to ask this is in the <q href="https://www.celephais.net/board/view_thread.php?id=60097&page=last">Coding Help</a> thread, I'll reply there.
#640 posted by
metlslime on 2021/07/12 18:37:51
also. laugh at my failure to make a hyperlink.