Author Topic: Item Variable Persistence?  (Read 3460 times)

I spawn two of the same gun.
I apply a variable to one of them.
I pickup both of them.
I then drop both of them.
The one gun that I applied a variable to should still have its variable. The other, same gun, shouldn't have a variable applied because I never applied one to it. Both of them must be unique. <- This doesn't happen, any variables applied before the items are picked up are effectively erased because they're technically different objects I assume (being re-created when dropped from inventory?).

This must be applied for every single item on the server, each spawned item on the map must be 'unique' in the fact that any (persistent) variable applied to it must stay applied to that specific item when it's picked up, in the inventory and dropped again.

Is this even possible + in a user friendly manner, e.g. applyPersistentVariable(%variable, %value, %item) ?

I don't think this has been done, and I don't think it'd be something someone who's new to TS should try to attempt (but if you do, we can help). I do like the idea though, and I've thought about coding support for items like you stated.

This doesn't happen, any variables applied before the items are picked up are effectively erased because they're technically different objects I assume (being re-created when dropped from inventory?).
This is correct.

To do this you would need to package serverCmdDropTool(%client, %slot) for item drops. Unfortunately, the only way to find the dropped item that I know of is with a radius search because the function has a superfluous return value (the player's currently mounted image). While this is rather hamfisted, it works. You would also package armor::onCollision(%this, %obj, %col, %fade, %pos, %normal) for item pickups. From there it's just a matter of storing the variables you want to preserve on the player when an item is picked up and transferring them to an item when it is dropped.

You would also package armor::onCollision(%this, %obj, %col, %fade, %pos, %normal) for item pickups.
there is also Weapon::onPickup(%this, %obj, %player, %amount), which would probably be better and easier to use because you don't have to worry about checking for classes or types and that crap
« Last Edit: July 09, 2015, 11:28:29 PM by Gytyyhgfffff »

Unfortunately, the only way to find the dropped item that I know of is with a radius search

I believe Item::onAdd(%item) should work (assuming that's a function, might be ItemData::onAdd(%data, %item) )


Can someone who has access to the encrypted .dso files post serverCmdDropTool , he could recreate it to return the dropped item.
Speaking of that, someone needs to make a resource of a bunch of fixed functions such as this, and make it load before other add-ons to keep compatibility.
« Last Edit: July 10, 2015, 09:50:41 AM by boodals 2 »

Can someone who has access to the encrypted .dso files post serverCmdDropTool , he could recreate it to return the dropped item.
Speaking of that, someone needs to make a resource of a bunch of fixed functions such as this, and make it load before other add-ons to keep compatibility.
I think it'd look like this:

Code: allGameScripts.cs.dasm (43 lines)
function ServerCmdDropTool(%client, %position)
{
    %player = %client.Player;

    if(!isObject(%player))
        return;

    %item = %player.tool[%position];

    if(!isObject(%item) || %item.canDrop != 1))
        return;

    %zScale = getWord(%player.getScale(), 2);

    %muzzlepoint = VectorAdd(%player.getPosition(), "0 0" SPC (1.5 * %zScale));
    %muzzlevector = %player.getEyeVector();
    %muzzlepoint = VectorAdd(%muzzlepoint, %muzzlevector);

    %playerRot = rotFromTransform(%player.getTransform());

    %thrownItem = new Item(){};       
    %thrownItem.setScale(%player.getScale());
    MissionCleanup.add(%thrownItem);
    %thrownItem.setTransform(%muzzlepoint @ " " @ %playerRot);
    %thrownItem.setVelocity(VectorScale(%muzzlevector, (20 * %zScale)));
    %thrownItem.miniGame = %client.miniGame;
    %thrownItem.bl_id = %client.getBLID();
    %thrownItem.setCollisionTimeout(%player);

    if(%item.className $= "Weapon")
        %player.weaponCount = (%player.weaponCount - 1);

    %player.tool[%position] = 0;
    messageClient(%client, 'MsgItemPickup', '', %position, 0);

    if(%player.getMountedImage(%item.image.mountPoint) > 0)
    {
        %item.image.getId();

        if(%player.getMountedImage(%item.image.mountPoint).getId() == %item.image.getId())
            %player.unmountImage(%item.image.mountPoint);
    }
}


Note that I didn't test it, just quickly copy pasted it together.

make it load before other add-ons to keep compatibility.
This isn't something add-on devs have control over, except for making the add-on something that would place it alphabetically first (like "AAAAA_AAAAA")

RTB loaded first only because a blockland update made it load first

except for making the add-on something that would place it alphabetically first (like "AAAAA_AAAAA")
This doesn't work on all operating systems, same reason why the add-on list is unordered for some people.

What you can do though is deactivate all active packages (make a list which you disabled!), activate your package, then activate all the others again. That should put your custom function at the end so all other stuff still works. Ofc if two add-ons try to do this to the same function it'll still fail.

Looks like you can just overwrite the function without a package and it'll work just fine with other add-ons packaging it
« Last Edit: July 10, 2015, 06:28:52 PM by Zeblote »

This isn't something add-on devs have control over

Sure it is, use this, or just a client.cs which packages the start game function, and executes the specific files before other add-ons (although that method wouldn't work for dedicated).
« Last Edit: July 10, 2015, 11:21:27 AM by boodals 2 »

Sure it is, use this

Note that you should be very careful about using this properly.

You can use this: http://greek2me.us/code/Support_PreLoad.cs

Please be considerate with it - we don't want it banned.

Edit: what you should actually do is just overwrite it without using a package. No need for the preload script.
« Last Edit: July 10, 2015, 06:46:49 PM by Greek2me »

Edit: what you should actually do is just overwrite it without using a package. No need for the preload script.
was just about to post this.

would other packages in addons correctly work with it?
ie a anti drop tools script loaded before it gets overriden

would other packages in addons correctly work with it?
ie a anti drop tools script loaded before it gets overriden
If you overwrite the function without using a package then existing packages will still work and call your function instead

If you overwrite the function without using a package then existing packages will still work and call your function instead

Oh wow, I didn't know that.. Well, I guess that makes it all a lot easier.