Project X Forums



It is currently Tue Mar 19, 2024 3:06 am

All times are UTC




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Crate spawn...
PostPosted: Sun Oct 28, 2018 8:09 am 
Offline
Betatester

Joined: Fri Jan 07, 2011 9:28 am
Posts: 2
Hi everyone, someone know how to increase crate limit on the map and drop lot of crates instead of 1 at turn begin, like in Rubber KAOS scheme?


UPD: I mean how to drop random crate from random weapon table, not only first and drop crate like a normal crate spawner (in random place and on the GROUND).

Example :

Code:
CCrateDesc d;

zero(&d);
d.wType = WCT_RANDOM;
d.type = CT_***;

new CCrate(Root, &d, DT_TELEPORT);


That code requires to set X and Y coordinates in the CCrateDesc class ('d' variable), i can use code like this to spawn it in random place :

Code:
d.X = GS->LevelSX * random();
d.Y = GS->LevelSY * random();


It have few problems :
First - It will work only in local game. Since random() will generate different numbers on remote computers and will cause desynchronization, i know that there are a way of sending synchronization message to other players, but maybe there are a way of just activating "built-in" game spawner and just call it few times to spawn as many crates as needed?
Second - Crate can spawn above water, at worm position, drum, other crate, etc.. wkRubberWorm never spawn crates like this, it spawn them like a normal game do - on ground at unused possible place.
Third - Crates spawned only from first weapon table.

Maybe there are a way to solve that problems?


Top
 Profile  
Reply with quote  
 Post subject: Re: Crate spawn...
PostPosted: Sat Nov 17, 2018 4:34 pm 
Offline

Joined: Wed May 24, 2017 9:35 am
Posts: 21
Hi everyone, someone know how to increase crate limit on the map and drop lot of crates instead of 1 at turn begin, like in Rubber KAOS scheme?

Project X has RubberWorm included. While in the game lobby, type /help to get a list of RubberWorm commands for your scheme.

Here's the crates related part:

craterate[value]: set how many attempts are made to spawn a crate between turns (1-255) (enables cratecount)
cratecount: show how many crates you collected (alias for craterate1)
crateshower: one crate every 5 seconds (not same of wwp crateshower! Overrides craterate!)
cratelimit[value]: set the max number of crates that can be in map (1-255)

If you don't want to have to type it in each time you host, do it once and then extract the scheme file from the replay. Open your PX scheme in the editor and Set WA Scheme to one you just extracted.

First - It will work only in local game. Since random() will generate different numbers on remote computers and will cause desynchronization, i know that there are a way of sending synchronization message to other players, but maybe there are a way of just activating "built-in" game spawner and just call it few times to spawn as many crates as needed?

Use GS->GetRandom(), it generates a synchronized random number.

Second - Crate can spawn above water, at worm position, drum, other crate, etc.. wkRubberWorm never spawn crates like this, it spawn them like a normal game do - on ground at unused possible place.

Ted made a crate spawning script for me once, here is how he went about it:

Code:
...

local nwC = new CCrate(Root->GetObject(25, 0), &cDesc, DT_CHUTE); // creates the crate but it does not have a spawn point yet
// the crate is created because we need to access its collision mask

int trywX = mapsizeX / 5;
int trywY = mapsizeY / 5;
int startwX = GS->GetRandom() % trywX;
int startwY = GS->GetRandom() % trywY;

for (int n = 0; n < (trywX * trywY); n++)
{
   int nwX = ((startwX + (n % trywX)) % trywX) * 5;
   int nwY = ((startwY + (n / trywY)) % trywY) * 5;
   CGObject * ow = Env->CheckCollision(nwC, nwX, nwY);
   if (ow == NullObj)
   {
      int hitX = 0;
      int hitY = 0;
      if (TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY) != NullObj && TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY)->ClType != OC_Worm && TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY)->ClType != OC_Crate && TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY)->ClType != OC_OilDrum && TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY)->ClType != OC_Mine)
        {
          nwC->PosX = nwX;
         nwC->PosY = nwY;
         nwC->X = nwX;
         nwC->Y = nwY;
         return true; // found a spawn point, return. This means exit this entire function.
      }
   }
}

nwC->Free(true); // we did not find a spawn point, lets destroy the crate we have created
return false;

...


Third - Crates spawned only from first weapon table.

Ted coded for weapons to be drawn from an array:

Code:
...

string wWeps[100];

wWeps[0] = "Double Bazooka";
wWeps[1] = "Homing Missile";
wWeps[2] = "Mortar";
wWeps[3] = "Homing Pigeon";
wWeps[4] = "Sheep Launcher";
wWeps[5] = "Grenade";
wWeps[6] = "Cluster Bomb";
wWeps[7] = "Banana Bomb";
wWeps[8] = "Battle Axe";
wWeps[9] = "Real Shotgun";
wWeps[10] = "Uzi";
wWeps[11] = "Minigun";
wWeps[12] = "Longbow";
wWeps[13] = "Dynamite";
wWeps[14] = "Mine";
wWeps[15] = "Sheep";
wWeps[16] = "Aqua Sheep";
wWeps[17] = "Mole Bomb";
wWeps[18] = "Air Strike";
wWeps[19] = "Mail Strike";
wWeps[20] = "Mine Strike";
wWeps[21] = "Mole Squadron";
wWeps[22] = "Super Banana Bomb";
wWeps[23] = "Holy Hand-Grenade";
wWeps[24] = "Flame Thrower";
wWeps[25] = "Salvation Army";
wWeps[26] = "MB Bomb";
wWeps[27] = "Petrol Bomb";
wWeps[28] = "Skunk";
wWeps[29] = "Priceless Ming Vase";
wWeps[30] = "French Sheep Strike";
wWeps[31] = "Mike's Carpet Bomb";
wWeps[32] = "Mad Cow";
wWeps[33] = "Old Woman";
wWeps[34] = "Bowling Ball Strike";
wWeps[35] = "Invisibility";
wWeps[36] = "Double Bazooka";
wWeps[37] = "Grenade";
wWeps[38] = "Banana Bomb";
wWeps[39] = "Real Shotgun";
wWeps[40] = "Minigun";
wWeps[41] = "Dynamite";
wWeps[42] = "Mine";
wWeps[43] = "Sheep";
wWeps[44] = "Aqua Sheep";
wWeps[45] = "Flame Thrower";
wWeps[46] = "Petrol Bomb";
wWeps[47] = "Skunk";
wWeps[48] = "Mad Cow";
wWeps[49] = "Old Woman";

int wWepsCount = 49;

...

int rwWep = GS->GetRandom() % (wWepsCount + 1); // pick a random weapon index
if (wWeps[rwWep] == "NORMAL")
{
   cDesc.wType = WCT_RANDOM;
}
else
{
   cDesc.wType = WCT_DEFINED;
   cDesc.amount = 1;
   local wwep1 = GS->GetWeaponByName(wWeps[rwWep]);
   if (wwep1 != NullObj)
   {
      cDesc.weapon = 100 * wwep1->GetPageIndex() + wwep1->GetWeaponIndex();
   }
}

...


UPD: I mean how to drop random crate from random weapon table, not only first and drop crate like a normal crate spawner (in random place and on the GROUND).

Example :

Code:
CCrateDesc d;

zero(&d);
d.wType = WCT_RANDOM;
d.type = CT_***;

new CCrate(Root, &d, DT_TELEPORT);


That code requires to set X and Y coordinates in the CCrateDesc class ('d' variable), i can use code like this to spawn it in random place :

Code:
d.X = GS->LevelSX * random();
d.Y = GS->LevelSY * random();


Ted's script uses collision checking to prevent spawning on worms, crates etc:

Code:
...

void nikolacrate::FirstFrame()
{
   mapsizeX = GS->LevelSX;
   mapsizeY = GS->LevelSY;
   mapwater = Env->Water;
}

...

int trywX = mapsizeX / 5;
int trywY = mapsizeY / 5;
int startwX = GS->GetRandom() % trywX;
int startwY = GS->GetRandom() % trywY;
   
for (int n = 0; n < (trywX * trywY); n++)
{
   int nwX = ((startwX + (n % trywX)) % trywX) * 5;
   int nwY = ((startwY + (n / trywY)) % trywY) * 5;
   CGObject * ow = Env->CheckCollision(nwC, nwX, nwY);
   if (ow == NullObj)
   {
        int hitX = 0;
      int hitY = 0;
      if (TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY) != NullObj && TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY)->ClType != OC_Worm && TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY)->ClType != OC_Crate && TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY)->ClType != OC_OilDrum && TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY)->ClType != OC_Mine)
        {
         nwC->PosX = nwX;
         nwC->PosY = nwY;
         nwC->X = nwX;
         nwC->Y = nwY;
         return true; // found a spawn point, return. This means exit this entire function.
      }
   }
}
   
nwC->Free(true); // we did not find a spawn point, lets destroy the crate we have created
return false;

...


A crate spawns at random intervals, in this case between one and two minutes, determined by the ncrateNextSpawn variable. Each frame, variable ncrateCounter increases by one until it is equal to ncrateNextSpawn which triggers a spawn.

Code:
...

if (ncrateCounter == ncrateNextSpawn)
{
   ncrateNextSpawn = 0;
   ncrateCounter = 0;
   spawnNikolaCrate();
}

ncrateCounter = ncrateCounter + 1;

...



And finally, here is Ted's complete script:

Code:
require utils;

int mapsizeX;
int mapsizeY;
int mapwater;
int ncrateCounter;
int ncrateNextSpawn;
int turnCounter;

void nikolacrate::Init()
{
   mapsizeX = 0;
   mapsizeY = 0;
   mapwater = 0;
   ncrateCounter = 1;
   ncrateNextSpawn = 0;
}

void nikolacrate::FirstFrame()
{
   mapsizeX = GS->LevelSX;
   mapsizeY = GS->LevelSY;
   mapwater = Env->Water;
}

override void CWorm::Message(CObject* sender, EMType Type, int MSize, CMessageData* MData)
{
   local CurrWorm = GetCurrentWorm();
   isCurrentWorm = (CurrWorm != NullObj && CurrWorm == this);
   if (isCurrentWorm== true)
    {   
      if (Type == M_FRAME)
      {
         // 60 frames per second, 3600 frames = 1 minute
         if (ncrateNextSpawn == 0)
            {
            ncrateNextSpawn = 36 + (GS->GetRandom() % 36); //random number between 3600 and 7200
         }
 
            if (ncrateCounter == ncrateNextSpawn)
            {
            ncrateNextSpawn = 0;
            ncrateCounter = 0;
            spawnNikolaCrate();
         }

         ncrateCounter = ncrateCounter + 1;

         if (ncrateCounter <= 0)
            {
            ncrateCounter = 1;
         }

      }

   }

   super;
}

bool spawnNikolaCrate()
{
   string wWeps[100];
   
   wWeps[0] = "Double Bazooka";
   wWeps[1] = "Homing Missile";
   wWeps[2] = "Mortar";
   wWeps[3] = "Homing Pigeon";
   wWeps[4] = "Sheep Launcher";
   wWeps[5] = "Grenade";
   wWeps[6] = "Cluster Bomb";
   wWeps[7] = "Banana Bomb";
   wWeps[8] = "Battle Axe";
   wWeps[9] = "Real Shotgun";
   wWeps[10] = "Uzi";
   wWeps[11] = "Minigun";
   wWeps[12] = "Longbow";
   wWeps[13] = "Dynamite";
   wWeps[14] = "Mine";
   wWeps[15] = "Sheep";
   wWeps[16] = "Aqua Sheep";
   wWeps[17] = "Mole Bomb";
   wWeps[18] = "Air Strike";
   wWeps[19] = "Mail Strike";
   wWeps[20] = "Mine Strike";
   wWeps[21] = "Mole Squadron";
   wWeps[22] = "Super Banana Bomb";
   wWeps[23] = "Holy Hand-Grenade";
   wWeps[24] = "Flame Thrower";
   wWeps[25] = "Salvation Army";
   wWeps[26] = "MB Bomb";
   wWeps[27] = "Petrol Bomb";
   wWeps[28] = "Skunk";
   wWeps[29] = "Priceless Ming Vase";
   wWeps[30] = "French Sheep Strike";
   wWeps[31] = "Mike's Carpet Bomb";
   wWeps[32] = "Mad Cow";
   wWeps[33] = "Old Woman";
   wWeps[34] = "Bowling Ball Strike";
   wWeps[35] = "Invisibility";
   wWeps[36] = "Double Bazooka";
   wWeps[37] = "Grenade";
   wWeps[38] = "Banana Bomb";
   wWeps[39] = "Real Shotgun";
   wWeps[40] = "Minigun";
   wWeps[41] = "Dynamite";
   wWeps[42] = "Mine";
   wWeps[43] = "Sheep";
   wWeps[44] = "Aqua Sheep";
   wWeps[45] = "Flame Thrower";
   wWeps[46] = "Petrol Bomb";
   wWeps[47] = "Skunk";
   wWeps[48] = "Mad Cow";
   wWeps[49] = "Old Woman";

   int wWepsCount = 49; // Moved this down here for visiblity

   if (mapsizeX < 100 || mapsizeY < 100)// stupid thing might not be set because stupid PX
    {
      mapsizeX = GS->LevelSX;
      mapsizeY = GS->LevelSY;
   }

   CCrateDesc cDesc;
   zero(&cDesc);
   cDesc.X = -1000;
   cDesc.Y = -1000;
   cDesc.type = CT_WEAPON; // CT_WEAPON CT_UTILITY CT_HEALTH

   int rwWep = GS->GetRandom() % (wWepsCount + 1); // pick a random weapon index
   if (wWeps[rwWep] == "NORMAL")
    {
      cDesc.wType = WCT_RANDOM;
   }
   else
    {
      cDesc.wType = WCT_DEFINED;
      cDesc.amount = 1;
      local wwep1 = GS->GetWeaponByName(wWeps[rwWep]);
      if (wwep1 != NullObj)
        {
         cDesc.weapon = 100 * wwep1->GetPageIndex() + wwep1->GetWeaponIndex();
      }
   }

   local nwC = new CCrate(Root->GetObject(25, 0), &cDesc, DT_CHUTE); // creates the crate but it does not have a spawn point yet
   // the crate is created because we need to access its collision mask

   int trywX = mapsizeX / 5;
   int trywY = mapsizeY / 5;
   int startwX = GS->GetRandom() % trywX;
   int startwY = GS->GetRandom() % trywY;
   
    for (int n = 0; n < (trywX * trywY); n++)
   {
      int nwX = ((startwX + (n % trywX)) % trywX) * 5;
      int nwY = ((startwY + (n / trywY)) % trywY) * 5;
      CGObject * ow = Env->CheckCollision(nwC, nwX, nwY);
      if (ow == NullObj)
      {
            int hitX = 0;
         int hitY = 0;
         if (TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY) != NullObj && TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY)->ClType != OC_Worm && TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY)->ClType != OC_Crate && TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY)->ClType != OC_OilDrum && TraceMask(nwC, nwC->ColMask, nwX, nwY, nwX, nwY + 1000, 4332670, &hitX, &hitY)->ClType != OC_Mine)
            {
            nwC->PosX = nwX;
            nwC->PosY = nwY;
            nwC->X = nwX;
            nwC->Y = nwY;
            return true; // found a spawn point, return. This means exit this entire function.
         }
      }
   }
   
   nwC->Free(true); // we did not find a spawn point, lets destroy the crate we have created
   return false;
}

override void CTurnGame::FinishTurn(int reason)
{
   turnCounter += 1;
   super;
}


Hope this helps. I tried my best to explain how it works, my knowledge is very limited. Let me know if something's still unclear.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 13 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Skin by Lucas Kane