Forum posts

Posted 5 years ago2019-02-17 14:26:39 UTC
in programmatically changing origin and angles Post #342048
You should always use UTIL_SetOrigin when changing an entity's origin, unless the origin variable is being used for storage (some entities do this, but it's a bad idea).

StudioFrameAdvance will trickle down into movement update logic which applies the animation movement to the NPC so the origin variable will be updated.

Changing pev->angles should work regardless though. Make sure nothing is resetting the angles elsewhere.
Posted 5 years ago2019-02-16 20:24:48 UTC
in TWHL Modded Minecraft Server (Final attempt) Post #342043
Posted 5 years ago2019-02-16 10:07:01 UTC
in programmatically changing origin and angles Post #342036
Show the code you're using.
Posted 5 years ago2019-02-15 12:08:44 UTC
in TWHL Modded Minecraft Server (Final attempt) Post #342028
I've put 3 sets of AE2 presses next to my front door if you need them. I had to clean out 3 meteors to find them all, so the nearby ones won't have any.
Posted 5 years ago2019-02-12 20:20:44 UTC
in TWHL Modded Minecraft Server (Final attempt) Post #342019
I don't think it worked, use the aluminum from this config: https://github.com/AllTheMods/ATM-3/blob/master/overrides/config/cofh/world/01_thermalfoundation_ores.json

And rename it to aluminum2 or something, because COFH won't regen it otherwise. It won't affect the actual ore, it's just the name used for COFH ore generation.
Posted 5 years ago2019-02-12 18:40:02 UTC
in TWHL Modded Minecraft Server (Final attempt) Post #342018
You also need to make sure that retrogen is enabled in COFH config.
Posted 5 years ago2019-02-12 17:21:17 UTC
in TWHL Modded Minecraft Server (Final attempt) Post #342016
I dug for about 10 minutes and found no aluminum. Which changes did you make and does the log show that it was retrogenerating the ore?
Something like
[12:56:00] [Server thread/DEBUG] [cofhcore/]: RetroGening [-3, 34].
should be showing up.
Posted 5 years ago2019-02-12 11:39:28 UTC
in TWHL Modded Minecraft Server (Final attempt) Post #342014
Thermal Foundation's Aluminium is disabled by default, so making aluminium brass is impossible early game.
It's possible to enable it without having to create a new world by using retrogen: https://github.com/CoFH/Feedback/issues/423

Just need to add the ore to the oregen file as well:https://old.reddit.com/r/feedthebeast/comments/5ys242/how_can_i_force_thermal_foundation_to_generate/desux5d/?st=js1p1oac&sh=d3f487ae
Posted 5 years ago2019-02-11 14:32:03 UTC
in SharpLife - Dot Net Core based modding p Post #342013
I did some research on how Unity handles commands and remote procedure calls (documentation for those here: https://docs.unity3d.com/Manual/UNetActions.html)

Unity rewrites the code to call a generated method that sends a message to clients (or servers, for Commands) containing the arguments. This makes it incredibly easy to add and use network messages.

Let me give an example by comparing it to GoldSource's approach and the approach i was planning on using with Protobuf.

Here's how you declare a network message and implement it:
//In player.cpp
int gmsgMyMsg = 0;

//In LinkUserMessages

//Maximum name length is 12 bytes
//Sending a string, so variable length message (-1)
//Maximum message size is 192 bytes
gmsgMyMsg = REG_USER_MSG( "MyMsg", -1 );

//In hud.h
int _cdecl MsgFunc_MyMsg(const char *pszName,  int iSize, void *pbuf);

//In hud.cpp
int __MsgFunc_MyMsg(const char *pszName, int iSize, void *pbuf)
{
	return gHUD.MsgFunc_MyMsg(pszName, iSize, pbuf );
}

//In CHud::Init
HOOK_MESSAGE( MyMsg );

//In hud_msg.cpp
int CHud:: MsgFunc_MyMsg( const char *pszName, int iSize, void *pbuf )
{
	BEGIN_READ( pbuf, iSize );

	CenterPrint( READ_STRING() );

	return 1;
}
This is just for a message in CHud, it's a bit different for a message in another Hud element.

And here's how you use it:
extern int gmsgMyMsg;

MESSAGE_BEGIN( MSG_ALL, gmsgTextMsg );
	WRITE_STRING( "my message" );
MESSAGE_END();
Assuming you're sending it to all clients reliably.

The Protobuf approach would be like this:
Declaring the message:
package SharpLife.Game.Networking.Messages;

message MyMsg
{
    string text = 1;
}
Receiving it in code:
public class SomeClass : IMessageReceiveHandler<MyMsg>
{
   public SomeClass(MessagesReceiveHandler handler)
    {
        handler.RegisterHandler(this);
    }

    public void ReceiveMessage(NetConnection connection, MyMsg message)
    {
        //-1 means centered for an axis
        _graphics.Text.DrawText(message.Text, -1, -1);
    }
}
And using it:
Context.Messages.SendMessage(new MyMsg{ Text = "my message" });
And now the Unity approach:
//Singleton component on some entity used to communicate from server to client for the hud
public class HudText : Component
{
    [ClientRpc]
    public void CenterPrint(string message)
    {
        _graphics.Text.DrawText(message, -1, -1);
    }
}

//Some other code in some other component
World.Instance.Hud.CenterPrint("my message");
Where World is a component used to identify the game world, placed on the entity that represents the world, that has a property public HudText Hud { get; }.

No registration is needed since that's all automatically generated behind the scenes, there's no need to define separate message types, no manual serialization or sending of messages, and the destination does not need to explicitly register itself since it is identified through its network identity.

This approach is way better and allows for optimizations that are not possible when user code has to manually register things. Since the game codebase is the same assembly for client and server there is no need to send the metadata to validate it either, as long as you've verified that the client is running the same assembly as the server, which is easy to do by comparing the AssemblyIdentity (strong name signing required to prevent spoofing).

It's also more efficient than Protobuf because it doesn't require the creation of objects to serialize.

Also unlike GoldSource and i think Source as well, Unity allows these sort of calls from client to server. In GoldSource the only way to communicate with the server is to send string commands, which is very restrictive. Being able to directly call the server with a specific command on a specific object can make things much easier.

As far as the technical side of things goes, i've found two libraries that could be used to do this: Reflection.Emit (part of .NET) and Mono.Cecil (also works on Core).
Since i've never worked with either i've asked for more information here: https://old.reddit.com/r/dotnet/comments/apg4qb/reflectionemit_vs_monocecil_which_is_best_suited/?st=js0fdqxt&sh=8db88032

I know that Cecil can do this, but if Reflection.Emit can do the same there is no reason to use a third party library.

As for how this works, it would be a post build step that modifies the assembly. The engine will then load the assembly and use the generated metadata to handle the remote calls.

This article indicates that it should be possible to debug assemblies that have been modified: https://johnhmarks.wordpress.com/2011/01/19/getting-mono-cecil-to-rewrite-pdb-files-to-enable-debugging/

So it shouldn't affect that.

This process of modifying assemblies is called weaving, and i've found a framework that does it. However, it's expected that you become a patron of the project if you use it, and that would mean everyone who uses SharpLife would also have to be a patron. Since this is supposed to be completely free i can't use that.

I don't expect that it will be too hard to implement a basic weaving tool by myself since it's largely the same as using Reflection, the only major difference being that i'll have to write IL instructions, which i'd probably have to learn anyway when using Fody: https://github.com/Fody/Home/blob/master/pages/addin-development.md

I think it may also be possible to use the same framework to optimize parts of the component system's internals, like the calls to non-virtual API methods (Update, Activate, etc), so that could prove useful as well.
Posted 5 years ago2019-02-09 14:45:02 UTC
in SharpLife - Dot Net Core based modding p Post #341998
I've done some research on ECS and a regular component system and i've found that using ECS would make it much more difficult to implement Half-Life.
For example things like triggering entities/inputs becomes more difficult because there's no object to trigger.

I think it's also more difficult for the average modder to learn how to use ECS, and if plugins are to be supported then it would be impossible to modify behavior on an object without duplicating the code for it since a component or group of components will be affected by systems that are not under the control of the plugin.

A regular component system like what Unity's had for years doesn't have these problems. While it does have lower performance it can do what's needed while still working like the original. The SDK's code can be converted to a component based design without having to change much, whereas using ECS requires a complete redesign.

I've also done some research to see if the greater overhead of a component system can be reduced, and i've found that it is actually possible: https://blogs.msmvps.com/jonskeet/2008/08/09/making-reflection-fly-and-exploring-delegates/

This article shows that's it's possible to get performance close to direct method calls using Reflection. Using Reflection instead of virtual method calls should make components much cheaper to use. I'll illustrate this with an example.

Here's a naive way to call Update on every component:
foreach (var entity in _entities)
{
    entity.Update();
}

//Entity's Update method
void Update()
{
    foreach (var component in _components)
    {
        component.Update();
    }
}
Not every component actually overrides Update but the cost of the call still exists.
Here's a way to optimize this using Reflection and delegates:
//Entity's Update method
void Update()
{
    foreach (var component in _components)
    {
        component._metaData.Update.Delegate?.Invoke(component);
    }
}
So now instead of a virtual method call it's a delegate invocation, but only if the delegate exists. The delegate is created when the component type is first used, as metadata that's generated once and then stored in each instance's _metaData field. This reduces the overhead, and since components rarely implement these methods (Update is called every game frame, hardly ever needed in Half-Life) it means the overhead involved in managing components is reduced.

It can be further reduced by moving from a purely object oriented approach to something more effective:
foreach (var component in _activeComponents)
{
    component._metaData.Update.Delegate?.Invoke(component);
}
Instead of calling the entity's Update method and letting that handle the updating of the components, all active components can be put into a single list and updated in one go by the game every frame. This eliminates the overhead involved with calling Entity.Update and iterating over each individual list so often.

So i think that this approach will work best for this particular project. In the future it may be possible to implement ECS, but that's something to consider after SharpLife V1 is all done.

Also, since this can allow the same code to run on client and server i can probably refactor the existing projects to merge client and server code some more, reducing complexity even more in both engine and game code.
https://www.zdnet.com/article/microsoft-to-offer-paid-windows-7-extended-security-updates/

MS will support 7 up to 2023 to patch security issues. By that point you should upgrade to a newer OS so you don't end up with problems.

You can't expect them to support a nearly 2 decade old OS forever. You can't expect application developers to do the same either. With support for XP going away in an upcoming version of Visual Studio we'll have to choose whether we want to continue targeting XP or having access to newer C++ language features.
In C#'s case the newest versions are already unsupported on older systems: https://docs.microsoft.com/en-us/dotnet/framework/get-started/system-requirements

If you honestly think that XP is secure then i hope for your sake that you're right.
I am still running XP and never have had any virus warnings... You must only have to keep you antivirus updated and never visit "extrange" or suspicious web sites. The same Win XP SP3 since 2009 without being reinstalled!! XD
Anti virus software can't protect against exploits in the OS itself. You're essentially claiming that closing the door and leaving it unlocked is enough to stop burglars. You can be compromised and not know it.
Posted 5 years ago2019-02-04 13:46:09 UTC
in SharpLife - Dot Net Core based modding p Post #341955
The idea behind ECS is that every system executes one at a time so tightly controlling order of execution goes against that.

I'm not sure if there are any practical differences in Half-Life, that's something that can be found by testing it. I can only say that it will be different in terms of when exactly it executes, but it might not be different enough to matter in the end. I'd consider any code and entity setups that are that reliant on this behavior to be bugged, since it's inconsistent.

Building an ECS doesn't seem to be terribly difficult, i've already got a small prototype going to see what it would take. I don't have to consider things like multithreading support so it's simpler than Unity's ECS. In the long run this might actually be simpler than just porting the code since it's so much easier to reuse stuff, and the networking side of things is actually simpler than what i was working on before.

For starters i'll build a non-networked system, but i don't expect there'll be many changes needed to make it networkable. If i apply what i've learned by studying Unity i can eliminate the need for separate client and server versions (much easier since state and behavior are decoupled) which was starting to complicate things a bit.

Save/restore is probably not much different from networking since they both deal with taking variables from components and converting them for something else. I might be able to reuse the code needed for networking to be used for that as well.
Posted 5 years ago2019-02-04 11:17:11 UTC
in SharpLife - Dot Net Core based modding p Post #341952
I've been doing some research on how modern engines handle entities and i've found that there are some options for SharpLife, at a cost.

GoldSource uses the older model of having each entity be a class inheriting from an entity base class. This means that when you create an entity, it will always be the class it is when it's first created. So you can't turn a door into a breakable, for example.

Newer engines allow you to add components to entities to separate out optional parts. Source does this, for example it has a VPhysics component to represents its physics mesh, if it has one.

This still uses the same rigid class based structure as before, but it avoids having variables in the class that aren't always used.

A more advanced version of this uses a sealed base class (can't be inherited from) and adds functionality to entities by adding components. This lets you change entities after they've been created, but adds a lot of overhead to update each component.

The newest kid on the block is called the Entity-Component-System, or ECS for short. You still have a sealed base class and components, but the components contain only state and not behavior. Behavior is provided by systems which can operate on a specific component type, or all entities that have a set of component types.

An ECS is much more efficient than a regular component system because it eliminates the overhead needed to update components. I'll illustrate this with some pseudo code.

A GoldSource style entity system works like this:
for each entity in entity_list do
    entity.think()
A component based system works like this:
for each entity in entity_list do
    for each component in entity do
        component.think()
An ECS works like this:
for each system in system_list do
    system.update()
There are far fewer systems than there are entities, and there are far fewer entities than there are components.

This makes an ECS more efficient since it reduces execution overhead. It also allows for more efficient memory usage by adding and removing components as needed.
Networking wise networking individual components is cheaper than networking an entire entity which can save a lot of bandwidth.

Unity for example networks components by networking up to 32 variables per component. By restricting the number of variables they can optimize networking to reduce dynamic memory allocations, something that isn't possible with a traditional hierarchical entity design like GoldSource and Source use.

Now comes the part that's specific to GoldSource: in GoldSource entities think during physics updates like this:
for each entity in entity_list do
    if entity is not world and entity is not player
        entity.move()
        entity.think()
The world never moves or thinks, and players are handled elsewhere.

The problem with this is that entities will sometimes check other entities near themselves while thinking. For instance teleporters and spawners will check if there are entities at the destination to see if they can move entities or perhaps need to telefrag them.

Because this can happen while other entities haven't moved yet, it's possible for inconsistent behavior to occur. Depending on whether an entity is in the entity list before or after another entity its behavior may change slightly as a result.

When using an ECS the physics update logic necessarily has to be changed to this:
for each entity in entity_list do
    if entity is not world and entity is not player
        entity.move()

for each system in system_list do
    system.update()
The result is that instead of executing each entity's think method after the last, all component systems think after all entities have moved. This is more correct than what GoldSource does, but it will change game behavior slightly in these cases where order of execution mattered.

I'm not aware of any cases where game logic is timed to happen in the correct order in the same frame, but i expect some minor behavioral changes to occur as a result of such a change in design.

So i have a decision to make. Do i go with the older entity design, use a basic component based system (remember, this increases overhead) or switch to an ECS?

For backwards compatibility purposes the original entity based approach will need to be emulated to support the limited entity data format. So a func_breakable would be an entity that has a brush model component and a breakable component, and perhaps an item spawner component that triggers when the breakable component triggers.

Once we can make a new map format it should be possible to use a more powerful entity creation process that would allow you to specify components to add to entities so for example you could make a breakable door relatively easily. This wouldn't happen any time soon though, since that requires a lot of changes.
Posted 5 years ago2019-02-03 11:52:04 UTC
in mod icon Post #341942
Nope, the engine only loads game.tga, and it uses the engine filesystem to load it. So by default it's valve/game.tga, but if your mod has one it'll use that instead.

I'm guessing the tga file is saved in such a way that it appears normal in viewers but gets read upside down by the engine and then flipped.
Posted 5 years ago2019-02-02 23:38:55 UTC
in houndeyes killing each other Post #341935
Then how are you creating the houndeyes? The string passed to Create will be used, but if the string is not allocated or a string literal it'll end up becoming garbage.
You can use MAKE_STRING( ALLOC_STRING( pszName ) ) to make sure it'll work, but if this code runs often you'll end up running out of memory in the engine since each ALLOC_STRING call allocates more memory.
Posted 5 years ago2019-02-02 17:44:47 UTC
in mod icon Post #341927
The engine seems to intentionally flip the image vertically, but i don't know why. I don't know why the original icon works either.
https://github.com/SamVanheer/NativeDllTester/releases/tag/V1.0

Apparently Github didn't like the previous exe upload, so i reuploaded it.
Posted 5 years ago2019-02-02 11:10:22 UTC
in houndeyes killing each other Post #341921
How are you setting the classname?
No, it's just a program you run locally.
Posted 5 years ago2019-01-28 15:34:20 UTC
in Opposing Force SDK Post #341873
I've put the game installation in its own repository: https://github.com/SamVanheer/half-life-op4-game

The README contains installation instructions. It's still unfinished, i'm currently implementing CTF. Should be done this week if all goes well.
Posted 5 years ago2019-01-27 19:41:54 UTC
in TWHL Modded Minecraft Server Post #341865
I don't think they've created a world yet.
Posted 5 years ago2019-01-26 19:39:27 UTC
in TWHL Modded Minecraft Server Post #341852
Looks like this might be it for you: https://minecraft.curseforge.com/projects/storage-tech
See also https://refinedstorage.raoulvdberge.com/wiki/addons

RS can store liquids, don't know about gas.
Posted 5 years ago2019-01-26 19:10:37 UTC
in TWHL Modded Minecraft Server Post #341850
AE2 can be configured not to use channels. I personally prefer RS since it's simpler and uses resources that are more easily mass produced (in the old mod pack at least) but with channels disabled they're very similar. AE2's approach to item storage is more expensive than RS so if you just need a mass storage mod then go for RS.

Check these for comparisons:
https://old.reddit.com/r/feedthebeast/comments/7s9yxp/ae2_vs_rs/?st=jrdukhw0&sh=06bdebfa
https://forum.feed-the-beast.com/threads/ae2-vs-refined-storage.224029/

I'd also suggest some kind of perpetual energy mod like SolarFlux. There may be solar panels in the mods you listed but SF has very powerful ones.

If you're into Chisel & Bits and BiblioCraft i'd suggest taking a look at ArchitectureCraft: https://minecraft.curseforge.com/projects/architecturecraft
Posted 5 years ago2019-01-25 22:30:11 UTC
in Opposing Force SDK Post #341842
I've implemented everything needed to play the entire singleplayer campaign.

I also went and fixed a bug with the Gene Worm since i encountered it: https://github.com/ValveSoftware/halflife/issues/917

Next up is weapon_penguin (CTF only afaik), the unused monster_geneworm (supposed to be able to move, not sure if the code can do it), then both weapons and NPCs are all done.

After that's it's CTF stuff, which also involves client side UI stuff.

Beyond that, i'll need to check existing gamerules for changes and add co-op gamerules, then check if anything else is needed.
Posted 5 years ago2019-01-24 20:07:59 UTC
in Opposing Force SDK Post #341827
The first 9 chapters are fully playable, up to and including Pit Worm's Nest. The next chapter uses a mortar and Black Ops aircraft that need to be implemented.
Once that's done it's just the Gene Worm and the singleplayer will be fully playable.
Posted 5 years ago2019-01-24 13:48:51 UTC
in Can't get func_trackchange to work Post #341823
The track change can only be moved if the train is either on it or far enough away.

Specifically, if the train's current path_track is the path_track that the track change is currently using, or the next or previous path_track connected to that one then you can only move the track change without the train being on it if it's 150 + train length units from the track change's origin, not taking into consideration the Z position of the track change.

So if you want to trigger it, make sure there are path_track entities right at the edges of the track change that the track change path_track entities connect with, that way the track change is only blocked if the train is very close to the track change (if the train is moving to one of the path_track entities at the edge). You'll want to position these so that the train can come to a stop without floating in the air or clipping through the track change when it moves.

If you want to make it possible to trigger the track change as much as possible, place another set of path_track entities right after the edge path_track entities so that the track change's logic doesn't see how close the train is until it's right at the track change. They could be as close as a unit apart, or maybe on top of each-other but that could cause problems with the train's direction.

crisis2 does it this way IIRC.
Posted 5 years ago2019-01-24 11:49:06 UTC
in Can't get func_trackchange to work Post #341819
A Sven Co-op map called crisis2 has a track change that can be moved freely without affecting the train. Maybe see how that's done?
I have some ideas for Half-Life maps that are beyond what the engine can do due to performance issues and limits that boil down to arbitrary numbers in the engine. It shouldn't be this hard to make maps that are larger than the engine supports right now, and performance shouldn't be affected by the technology used to handle graphics.
Yeah i think they want us to reverse engineer the older games as well, since the amount of information found in the libraries is way too much to account for just debugging purposes.
Posted 5 years ago2019-01-18 16:31:42 UTC
in Opposing Force SDK Post #341712
Does anyone have an up-to-date fgd for Opposing Force? I think i have this one: https://gamebanana.com/gamefiles/3972

It's missing some stuff, so if i could get a newer one i can add anything that's still missing.

Edit: found it, thanks Shepard: https://www.moddb.com/games/half-life-opposing-force/downloads/half-life-opposing-force-fgd-for-jackhammer
Posted 5 years ago2019-01-16 19:25:01 UTC
in Opposing Force SDK Post #341703
I've documented how the relationship table can be extracted from the game: https://github.com/SamVanheer/halflife-op4/wiki/Extracting-the-relationship-table

Requires a Linux VM or OS.
Posted 5 years ago2019-01-16 17:18:32 UTC
in SharpLife - Dot Net Core based modding p Post #341701
and i also trying to say, trigger changelevels arent working in singleplayer maps when playing MP, are they?
They're disabled for multiplayer, but it's easy to re-enable them. The hardest part about seamless transitions in the vanilla engine is that it wasn't designed for multiplayer use, so save games don't handle it. Also a fair amount of code in the SDK assumes the first player is in charge of gameplay, so things can break in weird ways. Easy to fix if you know what you're doing though.
i was thinking hl's coop mode is broken. i didnt know it wasnt
Half-Life itself doesn't have co-op at all, beyond an IsCoOp member in gamerules that's only used to find info_player_coop spawn points. Valve didn't finish it in time for Half-Life, but Op4 does seem to have it. Which brings me to: https://twhl.info/thread/view/19673
Posted 5 years ago2019-01-16 17:14:23 UTC
in Opposing Force SDK Post #341700
I'm currently working to implement Opposing Force in the Half-Life updated SDK: https://github.com/SamVanheer/halflife-op4/projects/1

I decided to do this now because i know that it will be a while before i can get to this if i make it part of SharpLife, and since i have to reconstruct the original C++ code anyway before i can convert it i figured i'd get it done now, so people can use it and find any mistakes/bugs before it gets converted.

So far i've implemented CTF gamerules, which is about 2000 lines of code. Other gamerules need to be updated, and the co-op gamerules need to be implemented as well.

I'm going to start with the NPCs now, since that's the interesting part and because that's what the largest part is.

Implementation is based on what's needed to make single maps work, starting with the training maps, then the campaign, then multiplayer. This way it can be tested more easily.

The ultimate goal is to make an SDK that completely implements Opposing Force. You won't be able to copy paste it into your own mod unfortunately since it changes existing SDK code (some network messages are different, gamerules are different too). When the time comes i'll port it to SharpLife, integrating all of the features so that you can play Opposing Force as well as Half-Life using the same base game, and use any features present in either in your maps.

I'm not doing a 1:1 reconstruction, there are places where i'm making use of newer language features and simpler code to make things easier. For example, iterating over players is done like this:
int teamCount[ MaxTeams ] = {};

for( auto pPlayer : UTIL_FindPlayers() )
{
	if( pPlayer->m_iTeamNum != CTFTeam::None )
	{
		++teamCount[ ( ( int ) pPlayer->m_iTeamNum ) - 1 ];
	}
}
I'm also using enum class, as you can see here. It keeps things cleaner and adds type checking, though it does have some drawbacks.

Iterating over entities is similar:
auto useDefault = true;

for( auto pEquip : UTIL_FindEntitiesByClassname( "game_player_equip" ) )
{
	useDefault = false;

	pEquip->Touch( pPlayer );
}
It's basically the same as before, but it's easier to use and you can't screw up the logic, like off by one errors in player iteration or a forgotten null check. It's also type safe if you need a specific class:
for( auto pFlag : UTIL_FindEntitiesByClassname<CTFGoalFlag>( "item_ctfflag" ) )
{
	if( pFlag->m_iGoalState == 2 )
	{
		pFlag->TurnOnLight( pPlayer );
	}
}
(Not all of the constants have been defined yet)

I've also added helpers to make it easier to do type conversions:
auto pPlayer = GET_PRIVATE<CBasePlayer>( pItem->pev->owner );
auto pOtherPlayer = CBaseEntity::Instance<CBasePlayer>( tr.pHit );
auto pFlag = pPlayer->m_pFlag.Entity<CTFGoalFlag>();
This eliminates the casts used otherwise, and also allows you to swap out the static_cast with a dynamic_cast to help find incorrect casts.
Posted 5 years ago2019-01-16 16:48:17 UTC
in SharpLife - Dot Net Core based modding p Post #341698
What are the entities did you tested successfully among, info_player entities, env entities, lights (I saw something about those), scripst,etc.? apart from what´s descibed in Post #339709.
That's the prototype for SharpLife, which ran under the original engine and only implemented game logic. It was essentially a converted SDK, but i scrapped it in favor of a complete rebuild, so just ignore all that.
Also, what programs are you using to edit-compile the source?
Visual Studio 2017 with C#7.3. The native wrapper uses C++17, but you'll probably never touch it since it's very simple and only does one thing.
Sorry for saying the "translation" thing, but, in your experience, what will be the major problems a non expert code will find when trying to "port" his/her code to SL?, many of us use tutorials all written in C++... ;)
No problems really, you'll just have to know which pev members map to which members in the new version. That's not really hard to figure out.
Sorry for my too basic questions, I know that maybe this is not the place to ask them because the info here reached a high level, but I am very interested in SL as I was in EHL and PS before, and I want to gather as much info as possible before making the decission to jump from C++ to C#, because if C++ was sometimes like chinese to me, I think I will not be able to learn korean. :glad: :walter:
You shouldn't make any decisions yet, this project is far from complete. I'd suggest checking out tutorials for basic Hello World stuff first, then maybe WPF since it requires the use of many language features.

If C++ is chinese then C# is dutch. It's way easier to learn and use. C++ has a lot of complexity and gotcha's that don't exist in C# and IntelliSense and the compiler will tell you how to fix most problems in C#. I'm using extensions that find code that can be improved which also helps out a lot.
btw can we make another thread for SL v2 for not to forget cool ideas. and not to flood this thread with weird ideas. :D
That's probably years away at this point, so i wouldn't bother just yet.
cause i have one more idea to implement: unbroken coop mode and seamless level transition in multiplayer server. :D
I was already going to implement co-op (Opposing Force has a co-op gamemode in it), what do you mean by unbroken?

Seamless level transitions basically revolve around 2 things: not showing the changelevel dialog and transitioning entities, which singleplayer code already does. For multiplayer all that's needed is to track which player is which since they don't remain connected during transitions. That's not very hard to do.
Posted 5 years ago2019-01-16 13:24:48 UTC
in SharpLife - Dot Net Core based modding p Post #341693
You're getting way ahead of yourself here. SharpLife doesn't even support all of the original engine's features yet, talking about adding a bunch of new stuff now is far too soon. At this rate it'll end up being some mythical super engine that can do anything but doesn't actually work yet.

We can talk about this stuff later on, when the initial version is finished. For now i'd like to focus on getting it all to work as it should.
Posted 5 years ago2019-01-16 10:01:38 UTC
in SharpLife - Dot Net Core based modding p Post #341690
You caught me!! ;) But, If it can load original content like the original HL does I will wait for sure. Also It appears to work without vgui.dll, which´s the major limitation of Xash when it comes to go greenlightened on STEAM, right? , I´m with ZWC for the last 14 years, one more will not harm me. :crowbar: :D
The original engine references vgui.dll, but my code doesn't use it.
In what a media playing is about, can we use other formats than AVI for the intro and sierra videos? also, I remember that in EHL you wanted to add background maps for the game menus, is this still present in SL?
The original engine can't play any videos, and SharpLife can't do it either. I'm not going to look into that any time soon either.
Background maps will be a thing for later, when the engine is stable.
Posted 5 years ago2019-01-15 20:36:26 UTC
in SharpLife - Dot Net Core based modding p Post #341682
I'm not translating it, i'm making a new engine that's also a mod that lets you make Half-Life mods and load original content.

If you want a better engine other than Xash then you'll have to wait.
Posted 5 years ago2019-01-15 20:19:19 UTC
in SharpLife - Dot Net Core based modding p Post #341680
Yeah your example is pretty much how save/restore should work.

C# is much easier to use than C++. I'll show a couple SDK examples to show this.

This is some code that shows up a lot in gamerules classes:
UTIL_LogPrintf(
	"\"%s<%i><%u><spectator>\" joined team \"spectator\"\n",
	STRING( pPlayer->pev->netname ),
	g_engfuncs.pfnGetPlayerUserId( pPlayer->edict() ),
	g_engfuncs.pfnGetPlayerWONId( pPlayer->edict() ) );
The equivalent in SharpLife would be:
_logger.Information( "\"{PlayerName}<{UserId}><{SteamId}><spectator>\" joined team \"spectator\"", player.PlayerName, player.UserId, player.SteamId );
Changing WONId to SteamId since WONId is always -1 now.

This is for logging, for normal string formatting you can just use string interpolation:
sprintf( text, "* you are on team '%s'\n", team_names[ ( int ) pPlayer->m_iTeamNum - 1 ] );
var text = $"* you are on team '{TeamNames[(int) player.TeamNumber]}'\n";
No possibility of buffer overflows here.

EHandles can also be made safer:
CTFGoalFlag pFlag = ( CTFGoalFlag* ) ( CBaseEntity* ) pPlayer->m_pFlag;

if( pFlag )
{
	pFlag->ReturnFlag();
}
Becomes:
EntityList.GetEntity<CTFGoalFlag>(player.Flag)?.ReturnFlag();
You don't have to do the double cast anymore (needed since EHANDLE can only be cast to CBaseEntity through its conversion operator), and the cast is safe instead of potentially creating an invalid object that can crash the game when used. Use of ? here is the same as the if check, if the object is not null call this method.

I've also had to write this code recently:
edict_t* pKiller = INDEXENT( 0 );

entvars_t* pEntKiller = pKiller ? &pKiller->v : nullptr;
None of that is needed in SharpLife, you can just use BaseEntity directly:
var killer = EntityList.GetEntityByIndex( 0 );
Since this just gets the world you can also get it through Context.Entities.World.

This is all pretty basic stuff, it gets easier once you deal with entities more:
pPlayer->pev->effects |= EF_NODRAW;
pPlayer->pev->flags |= FL_SPECTATOR;
pPlayer->pev->solid = SOLID_NOT;
pPlayer->pev->movetype = MOVETYPE_NOCLIP;
pPlayer->pev->takedamage = DAMAGE_NO;
pPlayer->m_iHideHUD |= HIDEHUD_HEALTH | HIDEHUD_WEAPONS;
pPlayer->m_afPhysicsFlags |= PFLAG_OBSERVER;
pPlayer->m_iNewTeamNum = CTFTeam::None;
pPlayer->m_iCurrentMenu = 0;
pPlayer->m_iTeamNum = CTFTeam::None;
player.Effects |= Effect.Nodraw;
player.Flags |= EntityFlag.Spectator;
player.Solid = Solid.Not;
player.Movetype = Movetype.Noclip;
player.Takedamage = TakeDamageMode.No;
player.HideHUD |= HideHud.Health | HideHud.Weapons;
player.PhysicsFlags |= PhysicsFlag.Observer;
player.NewTeamNumber = CTFTeam.None;
player.CurrentMenu = Menu.None;
player.TeamNum = CTFTeam.None;
Though i expect some of these variables will become obsolete since they're used for networking physics specific stuff. There's overlap here and there that can be eliminated.

Network messages will also be easier to use, right now they're just Protobuf messages so you can easily create and send them without having to worry about getting it wrong.

Debugging is also much easier since it'll tell you where a problem occurred, for example here's the log entry for a fatal error where it failed to load a sprite:
2019-01-10 00:34:47.640 +01:00 [ERR] A fatal error occurred
System.IO.FileNotFoundException: Could not resolve absolute path
File name: 'sprites\sewerfog.spr'
   at SharpLife.FileSystem.DiskFileSystem.GetAbsolutePath(String relativePath, String pathID) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.FileSystem\DiskFileSystem.cs:line 134
   at SharpLife.FileSystem.DiskFileSystem.Open(String relativePath, FileMode mode, FileAccess access, FileShare share, String pathID) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.FileSystem\DiskFileSystem.cs:line 222
   at SharpLife.FileSystem.FileSystemExtensions.OpenRead(IFileSystem self, String relativePath, String pathID) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.FileSystem\FileSystemExtensions.cs:line 254
   at SharpLife.Models.ModelManager.LoadModel(String modelName) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Models\ModelManager.cs:line 65
   at SharpLife.Models.ModelManager.InternalLoad(String modelName, Boolean throwOnFailure) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Models\ModelManager.cs:line 87
   at SharpLife.Models.ModelManager.Load(String modelName) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Models\ModelManager.cs:line 119
   at SharpLife.Engine.Server.Resources.ServerModels.LoadModel(String modelName) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine.Server\Resources\ServerModels.cs:line 75
   at SharpLife.Game.Server.Entities.BaseEntity.KeyValue(String key, String value) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Game.Server\Entities\BaseEntity.cs:line 228
   at SharpLife.Game.Server.Entities.Effects.EnvSprite.KeyValue(String key, String value) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Game.Server\Entities\Effects\EnvSprite.cs:line 45
   at SharpLife.Game.Server.Entities.ServerEntities.LoadEntity(List`1 block, Int32 index) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Game.Server\Entities\ServerEntities.cs:line 267
   at SharpLife.Game.Server.Entities.ServerEntities.LoadEntities(String entityData) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Game.Server\Entities\ServerEntities.cs:line 197
   at SharpLife.Game.Server.Entities.ServerEntities.MapLoadBegin(ITime gameTime, IMapInfo mapInfo, GamePhysics gamePhysics, String entityData, Boolean loadGame) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Game.Server\Entities\ServerEntities.cs:line 170
   at SharpLife.Game.Server.API.GameServer.MapLoadContinue(Boolean loadGame) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Game.Server\API\GameServer.cs:line 207
   at SharpLife.Engine.Server.Host.EngineServerHost.InitializeMap(ServerStartFlags flags) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine.Server\Host\EngineServerHost.cs:line 240
   at SharpLife.Engine.Engines.ClientServerEngine.FinishLoadMap(String startSpot, ServerStartFlags flags) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine\Engines\ClientServerEngine.cs:line 442
   at SharpLife.Engine.Engines.ClientServerEngine.StartNewMap(ICommandArgs command) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine\Engines\ClientServerEngine.cs:line 426
   at SharpLife.CommandSystem.Commands.Command.OnCommand(ICommandArgs command) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.CommandSystem\Commands\Command.cs:line 43
   at SharpLife.CommandSystem.CommandQueue.Execute() in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.CommandSystem\CommandQueue.cs:line 95
   at SharpLife.CommandSystem.CommandSystem.Execute() in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.CommandSystem\CommandSystem.cs:line 103
   at SharpLife.Engine.Engines.ClientServerEngine.Update(Single deltaSeconds) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine\Engines\ClientServerEngine.cs:line 196
   at SharpLife.Engine.Engines.ClientServerEngine.Run(String[] args, HostType hostType) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine\Engines\ClientServerEngine.cs:line 181
   at SharpLife.Engine.Host.EngineHost.Start(String[] args, HostType type) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine\Host\EngineHost.cs:line 36
It's a bit much but you get everything you need to know.

Compare this with GoldSource or even just C++ debugging where something like this is little more than a message box telling you there was a fatal error, without actually pointing you at the code that triggered it.

Once you get used to the language you'll find it's much easier, you won't want to go back to C++ after this.
Posted 5 years ago2019-01-15 16:53:22 UTC
in SharpLife - Dot Net Core based modding p Post #341673
Also it's written in a different language and has a different API so existing mods can't run under it anyway.
Posted 5 years ago2019-01-15 15:51:37 UTC
in SharpLife - Dot Net Core based modding p Post #341670
some corpses can gibbed with one hit. others are too much hits and they broke the hitting animation so without swinging the crowbar gibbing the corpses. (so politicians or media or something dont want to see a game where player constantly whacking a corpse. it seems so they removed animations.)
Depending on the NPC the health for corpses is set to half the original health value, so it could be quite high sometimes. Corpses are still subject to hitgroups so that might have something to do with it if you're essentially hitting a monster's feet.

The animation not playing is because the weapon prediction code doesn't run think functions on the client, i already fixed that in HLEnhanced. If you turn it off using cl_lw it should work as before, but in multiplayer it'll be laggier.
and you cant hit the corpse if that part of corpse is out of the otiginal monsters hull (bounding box)
That can probably be fixed by changing the bounding box upon death to match the shape when the NPC has come to rest. That depends on how sequences store hull sizes and stuff.
if hl2 smd to hl1 mdl compiler isnt posible, at least hl2 smd file to hl1 smd file can be made. the hl2 smd file format is easy to find, i guess. and there is info about hl2 smd at valve developer site.
It's possible to convert them, but information will be lost. That's why it may be better to use a new format that supports what you need before writing any converter tools.
Posted 5 years ago2019-01-15 15:30:03 UTC
in SharpLife - Dot Net Core based modding p Post #341666
what about 24 bit textures? ok if only v2 supports this. i cant wait to see v2 :)
V2 can support 32 bit just fine. I'm using a library made for image loading so eventually it could support any kind of image that that library supports.
and there is one more probleb about goldsrc. i dont want to use milkshape. its expensive and limited. i can use blender but its only supports hl2 smd files. so maybe you can make a compiler for hl2 smds to hl1 mdls.
I've never dabbled in Source programming and from what i know about it the studiomdl compiler for it is closed source. Maybe an easier to use format could be made for it one day though.
Better use hornetgun... But the entity limit is a problem (BIG PROBLEM) as you say. How much entities will support SL at a time before struggling?, also, and remember that I am quite an ignorant in coding, will it depend of the PC specs or this number will adapt itself independently of the system on which SL will run on?
SharpLife supports server-only entities which avoids the whole problem of networking entities to the client and having bandwidth issues. Projectiles don't need to be visible all the time, but networking is also much better so the client can handle more of it on the client, whereas GoldSource just does everything server side and then sends it to the client.

The system requirements are pretty high compared to GoldSource, but they haven't been set in stone. What i know right now is you'll need Windows 7 or newer, and a GPU capable or supporting fairly new versions of OpenGL (4.2 or newer). It may be high but do remember that hardware will catch up so the engine should have a long shelf life, longer than GoldSource considering how poorly the old renderer is supported now.

Pretty much all of the requirements can change depending on future development, and if Valve get their heads out of their collective asses and open source the engine i could do 64 bit development which would drastically increase the options available for bigger features.
Posted 5 years ago2019-01-15 11:09:48 UTC
in SharpLife - Dot Net Core based modding p Post #341662
Wad files don't support 32 bit textures so no.

You can already make projectile bullets in vanilla GoldSource, it just takes some effort. Modifying the RPG/AR grenade code should get you started.

What i talked about before about a V2 of SharpLife is what all the newer stuff should go into. V1 reproduces the original engine, using original file formats and stuff. Then backwards compatibility is broken by using new formats optimized for performance and customization and a better toolchain. If i can do that then i can solve all of the problems related to limitations caused by the file formats, texture name length being one of them.

That'll require a lot of support in the tools themselves. That's why i've been working on new compile tools, the map editor will also need to support the material system so i hope Sledge will support plugins that can provide a material system.
Posted 5 years ago2019-01-14 18:15:47 UTC
in SharpLife - Dot Net Core based modding p Post #341655
you told me 3d skybox and HD sky is posible.
are bigger maps and bigger textures posible too?
Both are possible.
And wad files are pain in the ass too xD could you make it so we dont need wadded textures.
A image file in the mod folder works very well, at least for developing a mod.
Due to how maps reference textures it's not currently possible to ditch wad files since you can only have 15 characters in a texture name, not nearly enough for directory names.
One question, what will be the structure of SL?, I mean, will it load a mod directly or it´ll depend of a Half-Life folder with the valve folder and all the rest of junk?, I like the way (don´t flame me please) Xash works. With it you must only create a folder with whatever name you want, you put the Xash exe, three dlls and the very folder of the mod in it and that´s all. Less than 10 Mb in size. And you can launch a full mod as if it was a standalone game (at least if you have all the needed assets in the MOD folder, of course).
SharpLife is an all-in-one package, so you'll make a mod that're the game libraries in SharpLife, and deploy the entire engine as a Half-Life mod. This allows each mod to change the engine as needed. Currently the assemblies directory is 11.2 Mb, but that includes debug builds and debug info, so it probably adds up to a similar size when it's all release builds.

SharpLife still needs a liblist.game file, used so the original engine can load the client.dll library which bootstraps SharpLife. This also allows Steam to find the mod and list it automatically.

It does depend on the valve folder, since it loads assets from there. The current design allows it to load assets from other game directories as well, so you won't have to copy over Opposing Force files for instance, which makes it easier to use game-specific files without having to redistribute anything. Ideally maps can specify which games they use assets from to help with error handling.

All of this is configurable in the code, so you can remove the dependency on original content if you want.
Posted 5 years ago2019-01-14 16:19:45 UTC
in SharpLife - Dot Net Core based modding p Post #341653
SharpLife currently has a limit set to 256 but it's a cvar that you can increase to any value, or you could remove the limit from the code altogether.

The only limit i've found is that really large images fail to load in some graphics backends, i'll need to reproduce the issue and report it to see if it's caused by Veldrid or something else.

SharpLife uses Veldrid to handle the graphics backend, and that supports OpenGL, Vulkan, DirectX, and Metal on Mac. All i need to do is add the code to let you choose and set up the correct backend (just a few lines of code for each backend), and it will work. Shaders can be written in GLSL and used by all backends, so it's pretty much ready to go already, though when i last tested it Vulkan had issues. They've probably been fixed by now though.
Posted 5 years ago2019-01-13 20:04:20 UTC
in SharpLife - Dot Net Core based modding p Post #341639
Both of those things should be possible.

I'm currently looking into how to make a material system to let you choose which shader is used for textures, but something like this will require new file formats and breaking changes in some places (e.g. no more render modes) so i'll have to choose between greater flexibility or supporting the original engine's way of doing things.

I'm thinking it may be better to go for a first version that supports the original formats, then making breaking changes in a V2 branch that focuses on maximizing performance at the cost of dropping features like render modes. There would probably be other ways to accomplish it though, like color can be done by using a proxy to fetch the color from an entity while rendering. I'll probably leave further research for later since it's quite complicated.
Posted 5 years ago2019-01-13 18:09:39 UTC
in SharpLife - Dot Net Core based modding p Post #341637
No, it'll take a while before everything gets to a functional level. I can't say how long it'll take.
Posted 5 years ago2019-01-13 17:44:14 UTC
in SharpLife - Dot Net Core based modding p Post #341635
SharpLife basically ignores the original engine and does everything itself. The original engine is only involved so SharpLife can be called a mod and used legally by modders.

As such i can implement the renderer using modern techniques which dramatically increases performance.
Posted 5 years ago2019-01-11 19:41:12 UTC
in SharpLife - Dot Net Core based modding p Post #341619
Could you please stop making off topic posts in this thread? I'm also not interested in you trying to get my attention for whatever you're working on.
It might, i'm not sure.