I found the fix, so I'm going to go through all the steps I used to help anyone that has similar issues in the future.
Because give_named_item works properly while create does not, I figured it had to be another property that isn't set during create. So, to determine that, I used the following to gather all of the properties for both create and give:
Syntax: Select all
from commands.say import SayCommand
from listeners.tick import Delay
from memory import make_object
from players.entity import Player
from weapons.entity import Weapon
comparison_dict = {}
@SayCommand('test1')
def on_test1(command, index, team_only=None):
weapon = make_object(
Weapon,
Player(index).give_named_item('weapon_ak47'),
)
store_values('give', weapon)
@SayCommand('test2')
def on_test2(command, index, team_only=None):
player = Player(index)
weapon = Weapon.create('weapon_ak47')
weapon.teleport(player.origin)
weapon.spawn()
Delay(0.1, store_values, ('create', weapon))
def store_values(key, weapon):
values = comparison_dict[key] = {}
for server_class in weapon.server_classes:
for prop, instance in server_class.properties.items():
try:
values[server_class.__name__ + '.' + prop] = getattr(
weapon,
'get_property_{prop_type}'.format(
prop_type=instance.prop_type,
)
)(prop)
except:
print(prop)
@SayCommand('compare')
def compare(command, index, team_only=None):
length = len(comparison_dict)
if length != 2:
raise ValueError(
'comparison_dict has {length} keys not 2!'.format(
length=length,
)
)
one, two = comparison_dict.keys()
other = comparison_dict[two]
for prop, value in sorted(comparison_dict[one].items()):
if value != other[prop]:
print(prop)
print('\t', value, other[prop])
Note that I used a Delay for the 'create' because some properties hadn't been set by that point. So, I first used the 'test1' command to give myself an AK using give_named_item. Then, after dropping that weapon, I used 'test2' to create the weapon and teleport it to my location. After it has compiled both sets of properties, I used the 'compare' command to print out all the differences in the server's console.
I copy/pasted the output into a txt file for easier reading. There were quite a few that I was sure were irrelevant, so I deleted them. In the end, I ended up with the following properties that I thought could be the one:
- CBaseCombatWeapon.m_iState
- CBaseEntity.m_iEFlags
- CBaseEntity.m_spawnflags
- CBaseEntity.touchStamp
- CEconEntity.m_AttributeManager.m_Item.m_bInitialized
- CEconEntity.m_AttributeManager.m_iReapplyProvisionParity
Using a Delay again, I set each of these values on the weapon in create:
Syntax: Select all
from commands.say import SayCommand
from listeners.tick import Delay
from players.entity import Player
from weapons.entity import Weapon
@SayCommand('test2')
def on_test2(command, index, team_only=None):
player = Player(index)
weapon = Weapon.create('weapon_ak47')
Delay(0.1, set_properties, (weapon, ))
weapon.teleport(player.origin)
weapon.spawn()
@SayCommand('add')
def on_test(command, index, team_only=None):
player = Player(index)
weapon = player.active_weapon
weapon.ammo += 50
def set_properties(weapon):
weapon.set_property_uchar('m_iState', 0)
weapon.set_property_int('m_iEFlags', 41992192)
weapon.set_property_int('m_spawnflags', 1073741824)
weapon.set_property_int('touchStamp', 0)
weapon.set_property_bool('m_AttributeManager.m_Item.m_bInitialized', True)
weapon.set_property_uchar('m_AttributeManager.m_iReapplyProvisionParity', 2)
I had to use a Delay because, without it, I actually never received the weapon. I'm not sure which of the properties caused this, but thankfully it wasn't the one we need for this fix.
Using this plugin, I was able to successfully receive the extra ammo and it stayed after reload. I then narrowed down the properties and determined that
m_AttributeManager.m_Item.m_bInitialized was the one that we are looking for.
Also of note, if I use the Delay, the reserve ammo I have after picking up is 0. However, if I set the property prior to my client picking up the weapon, I have full reserve ammo (90).