Skip to content

Custom weapon script loading system#498

Open
MyGamepedia wants to merge 8 commits intomapbase-source:developfrom
MyGamepedia:custom-weapon-script-loading
Open

Custom weapon script loading system#498
MyGamepedia wants to merge 8 commits intomapbase-source:developfrom
MyGamepedia:custom-weapon-script-loading

Conversation

@MyGamepedia
Copy link

@MyGamepedia MyGamepedia commented Feb 24, 2026

Instead of using hardcoded script name on each weapon class by using value stored in classname, now weapons will use weaponscriptname keyvalue and can dynamically change script by using ChangeScript input.

The core mechanism idea is simple, to decrease the amount of work and have backward compatibility, weapons override GetClassname() and replace real classname with script name, weapons GetClassname() still can return real classname by using m_iClassname directly. If weapon doesn't store any value for script, used fallback to classname, so a weapon without a script works in the same way as in original Source SDK.

Besides allowing to use any script you want, such trick also allows the player to own multiple weapons of the same class if they use different script values, for example, you can own both weapon_smg1 with script weapon_mp5 and weapon_smg1 with script weapon_mp7 at the same time, because the game thinks that these are two different weapons. This basically means that you can add unlimited amount of "new" weapons.

The ChangeScript input allows you to change script on fly. If a weapon owned by NPC or player, you can optionally reset old ammo clip count via sv_weapon_clips_reset_mode convar, 1 to set max clip value, 2 to set max clip value only if more then max clip, 0 for no changes. If a weapon owned by player, you can play idle or deploy animation via sv_weapon_vm_anim_reset_mode, 1 - deploy, 0 - idle.

To trigger weapon updates on client, used increment on m_iNeedsUpdate and compared with m_iOldNeedsUpdate, this is also done for ammo bar.

Replaced m_iClassname with GetClassname() or FClassnameIs() for some entities (like game_weapon_manager) in certain parts of their code to make them better work with this system.

Weapon selection doesn't let you to switch weapon if the weapon you want to switch to is your active weapon, this is important to avoid prediction glitch in multiplayer.

Respawned weapons will also save script the original weapon had, although it would be better to rework the respawn code to what was done for Black Mesa.

Matt pipe hack replaced with new code that uses this new system, because the model replacement doesn't work now for some reason (also because the hack doesn't work after save restore if Matt dropped the pipe by death).

Used ToCStr() in some places to make the solution compile.

Works fine with weapon_custom_scripted1.

Works properly in both singleplayer and multiplayer, although I didn't included weapon_physcannon changes for mp branch, because afaik it's WIP.

The only known issue I didn't fixed is that ammo bar incorrectly shifts for first few seconds when you switch scripts on melee weapon from melee weapon to weapon with clips (crowbar to ar2 for example), but why you want to use clips on a melee weapon ? For some parts of the code, we may should replace classname compare with dynamic_cast, for example I noticed that crowbar's hit sounds are fine if you don't use a script, but if you do, you will hear the hard metal hit sound.

If you ask about the copy right, the code from this VDC page belongs to me.

Here is few examples of what you can do with it (some of the vids are deprecated, I also recorded in Valve's Source SDK version, not Mapbase): vid1, vid2, vid3. This can be used for reskins, adding similar weapons, funny content, or adding "new" weapons for a project that doesn't have open source code. We could do even more with an expanded version of current scripts version, I think Black Mesa is good example.

mp7

Does this PR close any issues?

  • None.

PR Checklist

  • My PR follows all guidelines in the CONTRIBUTING.md file
  • My PR targets a develop branch OR targets another branch with a specific goal in mind

@MyGamepedia
Copy link
Author

Alr, hope it will work now.

The inline was important for client, so we now override CBaseEntity's GetClassname() method, to get real classname for a weapon - use m_iClassname directly.
@CoolDude034
Copy link

CoolDude034 commented Feb 25, 2026

would you take a look at the factory weapon code aswell?

Edit: im more talking about the CustomData/mapbase factory-based weapons, i.e it'd be cool to fix some issues with it

@CoolDude034
Copy link

CoolDude034 commented Feb 25, 2026

also Matt pipe hack replaced with new code that uses this new system, because the model replacement doesn't work now for some reason (also because the hack doesn't work after save restore if Matt dropped the pipe by death).
this is bad idea with what Mapbase goes for, keeping compatibility with vanilla SDK, and HL2's maps

Edit: actually nvm maybe the change might work out pretty well

@MyGamepedia
Copy link
Author

MyGamepedia commented Feb 25, 2026

would you take a look at the factory weapon code aswell?

I tried to use it, here is the results:
With ent_create weapon_custom_scripted1 weaponscriptname weapon_smg1 weapondatascript_name weapon_my_scripted vscripts_client weapondatascript_name I will get custom pistol.
ent_create weapon_custom_scripted1 weaponscriptname weapon_smg1 vscripts_client weapondatascript_name I will get smg1 with def params from the entity.
ent_create weapon_custom_scripted1 weaponscriptname weapon_smg1 weapondatascript_name weapon_my_scripted I will get custom pistol.
ent_create weapon_custom_scripted1 weaponscriptname weapon_smg1 I will get smg1 with def params from the entity.

So I guess it works pretty fine, default behaviors aren't broken and works with save restore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants