[Hexen II] AC Calculation
#2800 posted by Inky on 2020/04/10 09:25:02
Hello,
Not sure this is the right place for such a question, I beg you pardon in advance if not.
I am currently mapping for Hexen II and my question is extremely specific to that game. H2 has different kinds of "armor" items the player can grab, each absorbing a specific percentage of damage (actually depending on the player class, the hc code is pretty clear about how it works).
What I don't understand is the "AC" counter displayed in the HUD. This counter is incremented by a certain number of points when an armor item is picked up, but that number doesn't seem to be related to the actual percentage of damage the item can take. It is very puzzling and I have not been able this far to figure out how the HUD counter works.
Is there any chance one of you might have an idea about that???
Thank you so much in advance! :-)
[Hexen II] AC Calculation: Answer
#2801 posted by Inky on 2020/04/10 18:26:21
Just in case anyone would care, I got my answer here:
https://heretic.fandom.com/wiki/Thread:4326
Trenchbroom Commandline
#2802 posted by Inky on 2020/04/18 19:52:13
Hello,
Like some of you start to know, I map for Hexen II whose entities are sometimes tricky and not as well documented and known as Quake's ones.
That's why I learn a lot from Raven's original maps. The recurring type of question I have been asked to myself is "What is this spawnflag value for? How do they use it in vanilla H2?"
And basically I was launching a textual search on the entire set of .map files by Raven for all the occurrences of the given classname and inspected them one by one until I found one whose spawnflags value contained the desired power of 2 (which is not an easy calculation to work out in one's head). Sounds stupid and monstrously time consuming? It was!
I'm pretty sure you will laugh at me and explain that a far easier solution was available already but well, today I developed my own advanced multi-criteria search tool. It supports regexes and can filter entities by classname, property name and property value (which is searched among powers of 2 if needed). Each matching entity is returned with also its targetname and x y z position within the map.
The cherry on top of the cake would now be that by clicking on a result, Trenchbroom opens the map and moves the camera directly on the entity. Do you know of any command line parameter in Trenchbroom allowing such a thing?
(Sorry my posts are always more verbose than strictly necessary)
Thank you very much in advance!
#2803 posted by Inky on 2020/04/18 21:51:17
A cherry on top of the cherry on top of the cake would even be a command line parameter to open a map with TB and automatically load a pts file in the same action: usual shortcuts to follow the "pts line" would allow to go from one search result to the next instead...
Hmmm
#2804 posted by ijed on 2020/04/18 22:56:29
Worldcraft had a very nice feature called... entity report, I think.
Essentially it listed all entities and allowed you to filter the list by value. It also had basic error checking.
Ideally this would be a per-game thing, allowing the users to edit a .txt file or something to make new error checking parameters.
It's tempting to go into TB dev and help...
Ressurect/respawn Player In Singleplayer
#2805 posted by 3t0 on 2020/04/20 13:08:11
Hello again, I guess, this is proper forum to ask (I hope).
In doom forks there is often /budha mode (never have player health go below 1) and /resurrect command (that revives dead player in the spot they died).
During my years of dooming I started using those when quickly analyzing mod maps or doing my own tampering.
For me, they are much better suited for testing than /god.
I am curious about these things:
1. both of these (budha, resurrect) should be attainable with custom modded progs.dat, I believe. Am I right? Is there anything specific in C parts of engines to prevent that (given COOP this should work even with monsters)?
2. can I somehow resurrect with vanilla SP progs.dat? Using `/give h 100` will make my dead player "stand-up", but they cannot move and jump will immediately end level. Am I missing something or this is un-doable in vanilla?
I'm fairly sure that's un-doable in vanilla.
you can absolutely mod progs.dat to do this though
here is a quick and dirty proof of concept, no options just respawn in situ with 100 life
https://www.dropbox.com/s/b8sztids7x3xcyi/resurrect.zip?dl=0
#2808 posted by metlslime on 2020/04/20 16:52:46
Rubicon 2 has a resurrection cheat — impulse 666. You could look at that code.
Really Helpful
#2809 posted by 3t0 on 2020/04/20 23:54:42
Thank you guys this is awesome!
MapSearch & Inky's Hexen II Mapping Corner
#2810 posted by Inky on 2020/05/05 09:55:58
Hello everybody,
I answer to my own post #2802...
As said, I developed a very handy and powerful command line tool (supporting regexes and spawnflags search) to investigate map files and understand better how those at Raven & iD Software made their maps to learn from their example.
I'd be more than happy if it can be useful to some of you as it was for me : http://earthday.free.fr/Inkys-Hexen-II-Mapping-Corner/MapSearch.html
I would like to take the opportunity to also introduce my newly born website 'Inky's Hexen II Mapping Corner' which has the ambition of becoming a reference for those mapping for Hexen II. Anybody's advice or contribution to make the site grow faster and improve in quality would be most welcome. :-)
Feel also free to backlink it, if you like it, to make it gain some audience and help the small Hexen II mapping community to reinforce its network.
Last, a more direct request to you: has anybody out there the math and programming skills to help me with finding the 'x y z' position of a brush's center of gravity, after the brush definition stored in a map file???
Thank you in advance for your feedback! :)
QuakeC NOOb Needs Help
#2811 posted by Mezmorki on 2020/05/16 18:58:11
Hello all - long time!
I'm working on a server mod that is a mashup of a few different things:
- Reincarnation base map (old server DM mod from Gen and others)
- Added FrikBots
- Added Map Rotation
- Added Multi-skin support
I had a few things I'd like to try and clean up and desperately need some QC help as I have little clue with that I'm doing.
Here's the things I want to achieve:
#1 - Add custom skins to bots
I have custom player skins working for players (you can cycle through up to 32 skins attached to the player model). FrikBots has 16 different bot profiles, and I'd like set each different bot to use one of the custom skins. How can this be done (like what Omicron Bots did)?
I tried this, but it doesn't work:
{
self.b_pants = 11;
self.b_shirt = 0;
return "Vincent";
self.skin = 1;
}
Let's take one question at a time. Any idea how I can assign skins to the bots?
Taking The First Exit
#2812 posted by Preach on 2020/05/16 23:54:55
Hi Mezmorki. On the third line of your code you have
return "Vincent";
The return statement does two things. One is that it specifies the value which will be handed back to the code calling this function. But the other is that it ends the function and returns the value immediately. The code on line 4 which sets the skin is correct, but it never runs because the function exits on line 3.
If you swap the order of those two lines it should start working, but let us know if it doesn't...
That Worked!
#2813 posted by Mezmorki on 2020/05/17 15:49:41
Awesome - thanks for the help! It all worked fine.
Okay next topic. When players respawn a centerprint message pops up letting them know what skin they have active. I'd like to try and switch this message to an sprint (so it prints in the upper left corner instead of the center).
Here's the code:
// GeN >
player_stand1 ();
if (deathmatch)
{
makevectors(self.angles);
spawn_tfog (self.origin + v_forward*20);
}
spawn_tdeath (self.origin, self);
if((teamplay || (deathmatch & D_HH)) && (self.genteam))
SetTeam(self, self.genteam);
// *************************************************************************
// ** **
// ** M U L T I S K I N 1.1 (start) **
// ** **
// *************************************************************************
if (self.skin == 0) centerprint(self, "Respawning as... Quakeguy"); else
if (self.skin == 1) centerprint(self, "Respawning as... Doomguy"); else
if (self.skin == 2) centerprint(self, "Respawning as... Arnold the Terminator"); else
if (self.skin == 3) centerprint(self, "Respawning as... Arnold the Conan (4)");
//LINES REPEAT FOR ALL 32 SKINS...
// *************************************************************************
// ** **
// ** M U L T I S K I N 1.1 (end) **
// ** **
// *************************************************************************
};
If I replace "centerprint" with "sprint" it compiles okay, but no messages ever appear.
Any ideas?
Hmm
#2814 posted by Preach on 2020/05/17 23:49:47
I'd say check that you left the "self" part there - but you'll basically crash the whole server if you get that wrong when using sprint. Can you check to see if the message is getting logged in the console? Sometimes if there's a centerprint and a sprint happening at the same time, the one can wipe out the other.
#2815 posted by Mezmorki on 2020/05/18 01:33:19
Not sure what you mean by "left the self part" in place or not.
A given line could look like this in how I have it:
if (self.skin == 0) sprint(self, "Respawning as... Quakeguy\n"); else
I know most other sprint commands end with "\n" in the line to return?
Could there be something with the timing of respawning triggers that results in a different handling for sprint versus centerprint?
Seems like maybe I;m missing something obvious.
Hmmm
#2816 posted by Mezmorki on 2020/05/19 12:55:15
The message is getting printed to the console if I have the console open when I die.
Centerprint
#2817 posted by Preach on 2020/05/19 22:25:31
You got the self part right, I was worried you might have done something like
if (self.skin == 0) sprint("Respawning as... Quakeguy\n"); else
Is the change to sprint because you are centerprinting something else at the same time? If so, try disabling that for a moment and see if the sprint starts working.
Dang Engine Issue
#2818 posted by Mezmorki on 2020/05/22 04:10:49
turns out it was a quake engine issue of some sort. I was running and older version of qrack and I tried out a different engine and it worked. Updated Qrack and now it works in that too. :)
Trigger_changemusic + Saves
Alright. Thanks to Johnny Lew I have a trigger_changemusic in progs_dump however, I have no idea how to get this to work with savegames. Any guidance?
//thanks to Johnny Lew via changemusic.rar --dumptruck_ds
void() trigger_changemusic_touch =
{
if (!(other.flags & FL_CLIENT))
{
return;
}
if (!self.sounds)
{
objerror("ERROR: trigger_changemusic needs valid track number in sounds field");
return;
}
WriteByte(FL_SWIM, FL_MONSTER);
WriteByte(FL_SWIM, self.sounds);
WriteByte(FL_SWIM, self.sounds);
self.touch = SUB_Null;
self.nextthink = (time + 0.1);
self.think = SUB_Remove;
};
void() trigger_changemusic =
{
if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
return;
InitTrigger();
self.touch = trigger_changemusic_touch;
};
@mezmorki
#2820 posted by R00k on 2020/05/29 06:30:48
con_logcenterprint 1 is the option to print centerprint messages to console. setting it to 0 obv turns that off.
;)
Dumptruck:
#2821 posted by metlslime on 2020/05/29 07:45:07
you mean, you want to remember which music track was playing and restore that when the savegame loads?
Check out rubicon 2 source code, the function LoadSaveGameCallback, the logic to call in StartFrame, and the special variable loadsavegamecallback_done -- this setup allows you to do any necessary work after loading a save game, such as re-triggering client side looping sound effects.
In theory you can save the desired music track in some variable, and then when the game is reloaded, check that variable and re-trigger the music in your own version of LoadSaveGameCallback.
Metlslime
yep. I was looking through other mods yesterday. I should've known to start with Rubicon 2! thanks.
More Trigger_changemusic
I'm posting this for those who come after. It should plug into mods easily. As I was looking over Rubicon 2 code and overheating my pea-brain, Spike posted this on Discord. It works well so far but I need to test in various source ports. This isn't as flexible as what metl posted above but it works for this implementation. NOTE the & and * are correct below
add this to worldspawn in world.qc
world_sounds = &world.sounds; //Spike not read-only yet...
add this to defs.qc
nosave float *world_sounds; //via Spike fun times! nosave=noclobber
add to bottom of triggers.qc
void(float newtrack) changemusic =
{
*world_sounds = newtrack; //changing the field via a pointer
//world.sounds has now been changed via our pointer, newly connecting players (like those connecting after the game is loaded) will get sent the new cd track's number.
//let everyone currently on the server know.
WriteByte(MSG_ALL, SVC_CDTRACK);
WriteByte(MSG_ALL, newtrack); //initial track
WriteByte(MSG_ALL, newtrack); //looped track... should generally be set the same as the initial track as most engines ignore it entirely so it might as well be sane for those that care.
};
//thanks to jleww via changemusic.rar --dumptruck_ds
void() trigger_changemusic_touch =
{
if (!(other.flags & FL_CLIENT))
{
return;
}
changemusic(self.sounds);
self.touch = SUB_Null;
self.nextthink = (time + 0.1);
self.think = SUB_Remove;
};
void() trigger_changemusic =
{
if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
return;
if (!self.sounds)
{
objerror("ERROR: trigger_changemusic needs valid track number in sounds field");
return;
}
InitTrigger();
self.touch = trigger_changemusic_touch;
};
Correction
oops I just noticed
if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
return;
that is in progs_dump only - you won't need it elsewhere and it will cause an error on compile
|