I joke that people in TWHL insists you need to edit the half-life SDK code and produce your own custom DLLs at the slightest problem but I'm afraid this is the case for this one.Yup, that's the case.
#ifndef CLIENT_DLL
and #endif
block), look at the RPG's rocket, snark as a monster or placed tripmine for an example.Making the mapsPost some stuff of what you already did.
Splash Screen and Artworks
Sounds and Musics
Voice Acting
Designing (characters, maps, etc.)
Story and script writing
I think the lists of attributes and flags in the entity guide are mostly based off of the official FGDs. Which is unfortunate because the FGDs are far from accurate. For example the "Not In Deathmatch" flag actually works on any entity regardless of game or mod, so it should probably be included in every entity page?I share the same feeling as well about K/V pairs and spawnflags coming from the FGD rather than the game/mod's code. While this is inevitable for games/mods with closed source without reverse engineering (Counter-Strike: Condition Zero - Deleted Scenes and Team Fortress Classic for example), it would be best to rely on the game/mod's code whenever possible.
Yeah, I think those flag descriptions should probably just be in the relevant entity pages, doesn't make a whole lot of sense to have separate ones. I think these came from the old glossary section from before we had a wiki.I think this would make sense for "unique" K/V pairs and spawnflags that you would find in a single entity. I'm afraid it wouldn't work well for common K/V and spawnflags because it would be tedious (imagine duplicating and keeping consistency of the "Gag" spawnflag across all monsters entities for example).
But does it make sense to include a description of it on every page, when we might want to update that description some day?That's one of the counter-argument of the point above.
[include=Spawnflag:Not in deathmatch]
. The entity page would render the spawnflag page like if it was part of it's content. Need to update the description? Update the spawnflag page and it propagates automagically to all entities pages that uses it.The problem is that in the mod's grapth folder there are also .nrp files, which is curiously absent from valve's graphs folder. Even when the game can't edit the nod file (it's read only on FS level) it's still creating the nrp file, and seems to be relying on it. It seems to me that the AI system that uses the nod/nrp map combo is causing this problem, as the original game has no nrp files and it works fine.The NRP file is basically a "report" file (or log if you prefer) giving stats about nodes, links and more. It has no relation to the NOD file containing the actual data and thus can be wiped out when shipping/releasing maps and mods.
func_door
and func_door_rotating
entities are moveable while everything else is static (including func_train
, momentary_door
and such). This is bad because it causes the situation you described to happen. An approach that requires a test to be validated would be to replace these hardcoded classnames checks by checking if the entity's pev->movetype
is something else than MOVETYPE_NONE
.
Suspecting that maps saved by bspguy compels the engine to produce this problematic node formats, I resorted to ripent-ing the props I wanted to add (VHLT's). This failed, the problematic graph formats are generated, and the same freeze happens.The NOD file has a header and one of it's entries is the BSP's CRC checksum at the time the node graph was generated. Since you ripent-ed the BSP, the original CRC checksum is lost and thus a new one is generated (same checksum is used in multiplayer games to make sure the clients have the same map as the server). When the node graph loading code detect that the BSP's CRC checksum is different than the one that was stored while generating the graph, it assumes that the map changed and thus the old node graph is deleted to generate a new one. In other words, you can't use the original NOD file on a modified BSP.
Automatic mod setup is a plus, but I've done it so many times I speedrun it now. Besides, you won't be making myriads of mod configs, no?I think it would be best to have no "automatic game/mod setup", just let the level designer do the manual setup as there are too many things that can be different. At least an "import/export" function to backup/restore or share a game/mod profile to a beginner and have him update it or whatever.
and nobody uses the out of date free Jack, I hope.There are more users of "free J.A.C.K." than "paid Steam" ones that's for sure.
Trenchbroom could be a viable option, but half-life support is still under developmentA lot of progress has been made and support for GoldSrc is still on-going, it's use-able for geometry/texturing and probably most of the other things unless it's very specific.
Are you going to provide the ability to have these extra features toggle-able through preprocessor defines (like HLEnhanced's
- The overall goal is to make the smallest SDK possible while maintaining full functionality, and even expanding on features by using newer language/library features, and using code generation to help eliminate redundancy in things like save game code
- All of HLEnhanced features should eventually be re-implemented in this project, along with merging the unique features from Opposing Force Updated (weapons, NPCs, game modes) and Blue Shift Updated (handful of entities). This should make EHL the one-stop-shop for making a mod that mimics any of these 3 games, aside from the issue of Op4 weapons having grunt hands only
USE_OPFOR
) or separate repositories (like Half-Life Updated) to get a "HL SDK but just cleaned up"? I know this would require a lot of work but that would be nice for total conversions which do not rely or very little on existing entities.
The UI should be replaced entirely with a VGUI2 version. The code for that exists in HLEnhanced and will be ported over later on when i tackle that task. Eliminating the use of VGUI1 entirely will help to simplify things.By "the UI should be replaced entirely with a VGUI2 version", I'm guessing you are talking about all the existing VGUI elements (class menu, team menu, scoreboard, observer's control panel...) or are you extending this to other UI stuff (HUD based menu, ammo, crosshair, health...)?
skill.cfg
), you need to add a float
variable to the skilldata_t
structure, create the 3 CVARs themselves (cvar_t
), register them (CVAR_REGISTER
), "link" the variable and the CVARs using GetSkillCvar
and optionally provide a multiplayer override. This is a pain in the ass because:
cvar_t->name
syndrome?"CSkillCvar
class that would create the appropriate number of cvar_t
, register them automatically?BOOL m_fDamageDoubler
because it's going to be more confusing than helping.CBasePlayer
(player.h
) class declaration, add this:
float m_flDoubleDamageBonusTime;
bool HasDoubleDamageBonus()
{
return gpGlobals->time < m_flDoubleDamageTime;
}
If you are not familiar with HL SDK programming: gpGlobals->time
is the current game time.m_flDoubleDamageBonusTime
basically tells when the power up should be "off" and it gives you the state of the power up (game time higher than double damage time? It's off then. Double damage time higher than game time? It's on then) so you basically have 2 information in a single variable. That's why the handy bool HasDoubleDamageBonus()
is made and you should use it whenever you want to check if the player has the double damage bonus (it replaces your obsolete if ( m_fDoubleDamageBonus )
).CBasePlayer::Spawn
in player.cpp
, add m_flDoubleDamageBonusTime = -1.0f;
to the end to properly initialize the variable (because nobody likes problems).m_flDoubleDamageBonusTime
to the save/restore table of CBasePlayer
as a FIELD_TIME
to prevent issues when saving/loading games (again because nobody likes problems).m_flDoubleDamageBonusTime = gpGlobals->time + 15.0f;
.FireBulletsPlayer
method is responsible for firearms damage (crowbar, grenades and such are handled separately). That's where you do if ( pPlayer->HasDoubleDamageBonus() ) flDamage *= 2.0f;
to actually apply the damage bonus.I can fix the crowbar bug, but what's the double shot bug exactly? Just so i know what to look for.Probably the fact that client prediction can call events twice, I opened this related issue back in 2015.
CLIENT_WEAPONS
pre-processor define enabled. This will however require the programmer to move the client sided stuff back to the server for weapons. In other words: revert what Valve did when they introduced the client prediction system. An alternative is to set the cl_lw
CVAR (Console VARiable) to 0 (false).This is really interesting stuff! Does this fix the fast crowbar gib bug and the double shot bug from the glock's secondary fire?No for both.
pev->weapons
value to a C string that would match the animations names" and "how do I handle the standing up/crouched difference".LookupSequence
". In the end, you have something like this:
/**
* Returns the name of a sequence for this monster based on his stance (standing up or crouched), a specific name and his current weapon's name.
* @param szName The name of the sequence without the stance ("ref_" and "crouch_"), weapon's name ("python"...) and any underscore.
* @return The corresponding sequence name.
*/
const char *CMyMonster::GetSequenceName( const char *szName ) const
{
static char szResult[32];
strncpy( szResult, m_fStanding ? "ref_" : "crouch_", sizeof( szResult ) );
strncat( szResult, szName, sizeof( szResult ) );
strncat( szResult, "_", sizeof( szResult ) );
strncat( szResult, GetWeaponIDAsCStr(), sizeof( szResult ) );
return szResult;
}
/**
* Returns the name of the weapon this monster is currently using as a "C string".
* This is used to select the proper sequence when performing activities.
* @return This monster's current weapon name.
*/
const char *CMyMonster::GetWeaponIDAsCStr() const
{
if ( pev->weapons & HEVSCI_PYTHON )
return "python";
else if ( pev->weapons & HEVSCI_SHOTGUN )
return "shotgun";
else if ( pev->weapons & HEVSCI_MP5 )
return "mp5";
else if ( pev->weapons & HEVSCI_CROSSBOW )
return "bow";
else if ( pev->weapons & HEVSCI_RPG )
return "rpg";
else if ( pev->weapons & HEVSCI_GAUSS )
return "gauss";
else
return "onehanded";
}
Which you can use like this:
void CMyMonster::SetActivity( Activity NewActivity )
{
int iSequence = ACTIVITY_NOT_AVAILABLE;
void *pModel = GET_MODEL_PTR( ENT( pev ) );
switch ( NewActivity )
{
case ACT_IDLE:
iSequence = LookupSequence( GetSequenceName( "aim" ) );
break;
default:
iSequence = LookupActivity( NewActivity );
}
if ( iSequence <= ACTIVITY_NOT_AVAILABLE )
{
// Not available try to get default anim
ALERT( at_console, "%s has no sequence for act:%d\n", STRING( pev->classname ), NewActivity );
pev->sequence = 0; // Set to the reset anim (if it's there)
return;
}
// Set to the desired anim, or default anim if the desired is not present
if ( pev->sequence != iSequence || !m_fSequenceLoops )
pev->frame = 0;
pev->sequence = iSequence; // Set to the reset anim (if it's there)
ResetSequenceInfo();
SetYawSpeed();
}
Assuming your monster is crouched, uses the Python and you want the corresponding aim
sequence, GetSequenceName( "aim" )
will return crouched_aim_python
.func_tankrocket
entity (HGrunt uses them during the "On A Rail" chapter).When the game/mod starts, issue the map <your fancy background map here> commandThis can be done by putting the command in a RC or CFG file.
have some kind of if ( thisIsMyMenuMap ) condition to show that new main menu (powered by VGUI or another UI framework if you use one). Then you issue commands depending on the buttons being clicked. For example: "New Game" button would issue map <your first map here>. "Load game" would load up the default load dialog.That would be client sided.
void CFuckfinger::SecondaryAttack(void)
{
void;
}
If your weapon does not have a secondary attack, then it is useless to override it in your weapon class, also that void;
thingy is useless (maybe you meant return;
?)void CFuckfinger::Reload(void)
{
// Ammo check and actual reload code here
if (iResult)
{
m_flTimeWeaponIdle + UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15);
}
}
The problem here is that you calculate the next weapon idle time but you never assign the result, you missed a m_flTimeWeaponIdle =
void CFuckfinger::WeaponIdle(void)
{
// Reset empty sound, autoaim and "time to idle check" code here
if (m_iClip != 0)
{
int iAnim;
float flRand = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 0, 1);
if (flRand <= 0.5)
{
iAnim = FUCKFINGER_IDLE;
m_flTimeWeaponIdle + 70.0 / 30.0;
}
else if (flRand <= 0.7)
{
iAnim = FUCKFINGER_IDLE;
m_flTimeWeaponIdle + 60.0 / 16.0;
}
else
{
iAnim = FUCKFINGER_IDLE;
m_flTimeWeaponIdle + 88.0 / 30.0;
}
SendWeaponAnim(iAnim, 1);
}
}
There are 3 problems here, the first one is the identical to the reload problem (you calculate the next idle times but you never assign them). The second problem is that you forgot UTIL_WeaponTimeBase()
in the calculation which is the current game time. And the final problem is that you are randomly picking one of 3 possibles scenarios but all of them play the same idle animation (the idle time being the only difference). You could simplify your WeaponIdle
function to something like this:
void CFuckfinger::WeaponIdle()
{
ResetEmptySound();
m_pPlayer->GetAutoaimVector(AUTOAIM_10DEGREES);
// Play idle animation only if it is time to do so and the clip/magazine isn't empty
if ( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() || m_iClip <= 0 )
return;
SendWeaponAnim( FUCKFINGER_IDLE );
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 3.0f; // Assuming your idle animation duration is 3 seconds
}
Next time when you post code here, post it in a code block so that's it's easier for everyone to read, see the formatting help wiki page for details.map <your fancy background map here>
command, that map would trigger an entity or your code would have some kind of if ( thisIsMyMenuMap )
condition to show that new main menu (powered by VGUI or another UI framework if you use one). Then you issue commands depending on the buttons being clicked. For example: "New Game" button would issue map <your first map here>
. "Load game" would load up the default load dialog.There will be a SL Single-Multiplayer source then?It is not that I will start anything in a near future, but it could be interesting for people to start doing something cool with the GS code using your "mod".No, Solokiller said in a previous post when he redesigned the engine that the game source code is gonna be a "client/server/shared" architecture where client-only stuff goes into the client part, the server-only stuff goes into the server part and everything common to the client and server goes into the shared part.
btw how long do you think until someone will create a non vr version mod ? XDA "flat" version of HL:A would be "boring" as you would lose all the interactions that VR grant.
My speculation is, less than 4 months after the SDK releases, if they provide one.Right now, it is confirmed that we'll have Hammer 2 for HL:A. As for a "standard source code" à la GoldSrc/Source (even complete), nothing official yet.
Give me some info before... What game mode will be used, singleplayer with deathmatch 0 or multiplayer with deathmatch 1? Is gauss hopping allowed?Likely singleplayer, as for gauss hopping, it depends if Spirit of Half-Life 1.8 allow it in singleplayer.
I would have rushed something out in the last year or so to get it over the line.Don't make the same mistake as we did with Half-Rats: Parasomnia. Take the time you need to finish it and most importantly: have a lot of people playtest the shit out of it (different play styles, profiles...)
Should probably finish this mod, huh?Not sure if this is the truth...... or a trap for hype.
Very excited. Have an idea in my head that I've wanted to try for ages. Does it strictly have to be HL1 / Source or is something like Sven Coop applicable?The competition refers to "the" player in singular, so I'm guessing that only singleplayer games in the Valve universe are allowed.
Well, the issue there would be the difference between Source and Goldsource. I have no idea how to set up a Source mod.I can handle that.
And can we get an official word specifically on custom code, because I feel like that is sort of a different level of custom content that doesn't tend to fit with these sorts of competitions.To be fair, the code and binaries would need to be open to everyone even non-programmers.