Author Topic: addItem in a schedule  (Read 4205 times)

I'm trying to add a delay on the creeper gamemode's creepbomb, so the spores aren't killed off immediately.

The message comes through properly, but the item does not appear.

Code: [Select]
%DelayTime = $Creep::BombDelay * 60000;
schedule(%DelayTime,%player, addItem, nameToID(CreepBombItem), %client);
schedule(%DelayTime,0,messageClient, %client, 'MsgItemPickup', "Your creep-bomb is now available.");

addItem is not a default function. Ensure that it is available in the given environment.

in addition, the way schedules are usually called on an object is as follows:
%player.schedule(%delayTime, addItem, nameToID(CreepBombItem), %client);

i'm pretty sure replacing the 0 with the object in question does work as well, however i've honestly never tested extensively or seen it done anywhere else before, so i'm not certain if that's functional or not.

not much else to add without the entire relevant code unless i missed something

I implemented your suggestion, but got the same results.  Here is the entire function.
Also, the addItem function is used successfully in other functions of this gamemode, so I assume it's fine to use it.
Code: [Select]
function GameConnection::spawnPlayer(%client)
{
        Parent::spawnPlayer(%client);
        %client.updateSuperCreeperScore();
        
        if(!isObject(%client.player)) return; // slayer removes late joining players and this can cause errors here
        
        %player = %client.player;
        
        // CREEPER VARIABLES //
        %client.kills = 0;
        %player.nochase = 0;
        
        // START ITEMS //
        // Anti-Creeper Loadout:
        if($Creep::GameMode == 0 || $Creep::GameMode == 3 || $Creep::GameMode == 5)
{
            // are we using a map with shop functionality?
            if($Creep::UseShop)
{
                switch(UpgradeMan.getValue(%client.bl_id, "CreepKillLvl"))
{
                    case 1:
                        %player.addItem(nameToID(CreepKillWeakGunItem),%client);
                    case 2:
                        %player.addItem(nameToID(CreepKillGunItem),%client);
                    case 3:
                        %player.addItem(nameToID(CreepKillStrongGunItem),%client);
                    case 4:
                        %player.addItem(nameToID(CreepKillVStrongGunItem),%client);
                }
                
                if(UpgradeMan.getValue(%client.bl_id, "CreepBombLvl") > 0 && !$Creep::NoBombs)
{
                    if(UpgradeMan.getValue(%client.bl_id, "CreepBombLvl") == 1)
{
%DelayTime = $Creep::BombDelay * 60000;
%player.schedule(%delayTime, addItem, nameToID(CreepBombItem), %client);
schedule(%DelayTime,0,messageClient,%client,'MsgItemPickup',"Your creep-bomb is now available.");
}
                    else
{
%DelayTime = $Creep::BombDelay * 60000;
%player.schedule(%delayTime, addItem, nameToID(CreepBomb2Item), %client);
schedule(%DelayTime,0,messageClient,%client,'MsgItemPickup',"Your creep-bomb is now available.");
}                  
                }
            }
else// if not just give everyone the bog standard
                %player.addItem(nameToID(CreepKillGunItem),%client);  
        }
        
        // Creeper Planter Loadout:
        // not in yet
        
        // Competitive Loadout:
        // not in yet
        
        // That Bastard Loadout:
        // not in yet
        
        
        // LIVES //
        
        // can players respawn in the current gamemode?
        if($Creep::GameMode != 3 && $Creep::GameMode != 4 && $Creep::GameMode != 5) {
            %client.setLives(1); // if so, one life
        }
        
        // LOCATION //
        // players spawn on bricks named "spawn"
        %pos = getRandomPosOnBrick(getRandomSpawnBrick());
        %player.settransform(%pos);
        %player.setvelocity("0 0 0");
        return;
    }
« Last Edit: December 22, 2014, 02:04:11 AM by Tezuni 2.0 »

You are routing to the else because you are not using the shop functionality as far as i can see and are instantly doing %player.additem(...);
All the fancy schedules seem to be only used if the shop is enabled.

I've created a different kind of code for the item stuff since the addItem event is kind of broken.

findItemByName(%uiName) - returns the datablock name of the item
Player::addNewItem(%player,%uiName)  - finds the item that you searched for (ex: %obj.addNewItem("Rocket L");) and gives it to the player.

Code: [Select]
function findItemByName(%item)
{
for(%i=0;%i<DatablockGroup.getCount();%i++)
{
%obj = DatablockGroup.getObject(%i);
if(%obj.getClassName() $= "ItemData")
if(strPos(%obj.uiName,%item) >= 0)
return %obj.getName();
}
return -1;
}

function Player::addNewItem(%player,%item)
{
%client = %player.client;
if(isObject(%item))
{
if(%item.getClassName() !$= "ItemData") return -1;
%item = %item.getName();
}
else
%item = findItemByName(%item);
if(!isObject(%item)) return;
%item = nameToID(%item);
for(%i = 0; %i < %player.getDatablock().maxTools; %i++)
{
%tool = %player.tool[%i];
if(!isObject(%tool))
{
%player.tool[%i] = %item;
%player.weaponCount++;
messageClient(%client,'MsgItemPickup','',%i,%item);
break;
}
}
}
//registerOutputEvent(Player,addNewItem,"string 50 50");

I've created a different kind of code for the item stuff since the addItem event is kind of broken.

Nice.  How would this work in a schedule?  Could you do an example?

Nice.  How would this work in a schedule?  Could you do an example?

%player.schedule( $Creep::BombDelay * 60000 , addNewItem , CreepBombItem );

Thanks guys, I got it working with using what Advanced Bot and Trinick posted.

You could also do
%player.schedule( $Creep::BombDelay * 60000 , addNewItem , "Item's ui name (Doesn't have to be the full name unless there are duplicates of it)" );

-snip-

You really should do some caching of items if you use findItemByName often. Looping through up to 4000 objects every time this is called is not a good idea. You can implement it seamlessly by putting it inside the function itself.

Code: [Select]
function findItemByName(%item)
{
if(isObject($Creep::Item::Datablock[%item]))
return $Creep::Item::Datablock[%item];

for(%i=0;%i<DatablockGroup.getCount();%i++)
{
%obj = DatablockGroup.getObject(%i);
if(%obj.getClassName() $= "ItemData")
if(strPos(%obj.uiName,%item) >= 0)
{
$Creep::Item::Datablock[%item] = %obj.getName();
return %obj.getName();
}
}
return -1;
}

While this doesn't really help much from the 'find' side (it will only store stuff by the string you enter, if you enter "Akimb", "Akimbo", "imbo", etc it wont help at all), it will help if you hardcode UI names into the script.


Honestly though its a hell of a lot easier just to enter the name of the datablock.
« Last Edit: December 23, 2014, 04:08:16 AM by boodals 2 »

Boodals, inside the for loop you're returning the object name, and then in the first if statement you're returning the object lol. This will yield in different results.

Boodals, inside the for loop you're returning the object name, and then in the first if statement you're returning the object lol. This will yield in different results.

Oops, well it makes no difference on functionality really. Fixed anyway.

Oops, well it makes no difference on functionality really. Fixed anyway.

Yeah I was just letting you know lol.

Apparently the schedules are only working for me and nobody else.  Anyone know why that'd be and how to fix it?

Code: [Select]
function GameConnection::CanBuyCreepBombs(%client)
{
%client.CanBuyCreepBombs = 1;

if(!isObject(%client.player))
return;

MessageClient(%client,'',"You may now purchase creep bombs with /buy creepbomb.");
}

    function GameConnection::spawnPlayer(%client)
{
        Parent::spawnPlayer(%client);
        %client.updateSuperCreeperScore();
        %player = %client.player;

        if(!isObject(%client.player))
return; // slayer removes late joining players and this can cause errors here
        
//buy bomb delay
%client.BoughtBombs = 0;
%client.CanBuyCreepBombs = 0;
cancel($BuyBombSchedule);

if($Creep::BuyBombDelay)
$BuyBombSchedule = %client.schedule( $Creep::BuyBombDelay * 60000 , CanBuyCreepBombs );

        // CREEPER VARIABLES //
        %client.kills = 0;
        %player.nochase = 0;
        
        // START ITEMS //
        // Anti-Creeper Loadout:
        if($Creep::GameMode == 0 || $Creep::GameMode == 3 || $Creep::GameMode == 5)
{
            // are we using a map with shop functionality?
            if(!$Creep::DisableUpgrades)
{
                switch(UpgradeMan.getValue(%client.bl_id, "CreepKillLvl"))
{
                    case 1:
                        %player.addItem(nameToID(CreepKillWeakGunItem),%client);
                    case 2:
                        %player.addItem(nameToID(CreepKillGunItem),%client);
                    case 3:
                        %player.addItem(nameToID(CreepKillStrongGunItem),%client);
                    case 4:
                        %player.addItem(nameToID(CreepKillVStrongGunItem),%client);
                }
                
                if(UpgradeMan.getValue(%client.bl_id, "CreepBombLvl") > 0)
{
if(!isObject(%client.player))
return;
if($Creep::DisableBombs)
return;

                    if(UpgradeMan.getValue(%client.bl_id, "CreepBombLvl") == 1)
{
cancel($BombDelayScheduleNotify);
cancel($BombDelaySchedule);
$BombDelaySchedule = %player.schedule( $Creep::DefaultBombDelay * 60000 , addNewItem , CreepBombItem );
$BombDelayScheduleNotify = schedule( $Creep::DefaultBombDelay * 60000 , 0 , messageClient,%client,'MsgItemPickup',"Your default creep-bomb is now available.");
}
                    else
{
cancel($BombDelayScheduleNotify);
cancel($BombDelaySchedule);
$BombDelaySchedule = %player.schedule( $Creep::DefaultBombDelay * 60000 , addNewItem , CreepBomb2Item );
$BombDelayScheduleNotify = schedule( $Creep::DefaultBombDelay * 60000 , 0 , messageClient,%client,'MsgItemPickup',"Your default creep-bomb is now available.");
}                  
                }
            }
else// if not just give everyone the bog standard
                %player.addItem(nameToID(CreepKillGunItem),%client);  
        }
        
        // LIVES //
        
        // can players respawn in the current gamemode?
        if($Creep::GameMode != 3 && $Creep::GameMode != 4 && $Creep::GameMode != 5) {
            %client.setLives(1); // if so, one life
        }
        
        // LOCATION //
        // players spawn on bricks named "spawn"
        %pos = getRandomPosOnBrick(getRandomSpawnBrick());
        %player.settransform(%pos);
        %player.setvelocity("0 0 0");
        return;
    }
« Last Edit: January 01, 2015, 09:35:36 PM by Tezuni 2.0 »

Have you tried turning it off and on again?

Maybe instead of doing the schedules on global variables do them on the clients themselves? Like
%client.BombDelaySchedule = schedule(blah,#,etc.);