Battlezone Universe

Battlezone Universe => Battlezone 2 => Maps and Modding => Topic started by: TheJamsh on December 28, 2007, 05:30:30 PM

Title: making a new .dll
Post by: TheJamsh on December 28, 2007, 05:30:30 PM
was going to post this in a dead thread didnt think anyone would answer...

i need to know how i can setup an instant .dll to first use the correct AIP plans i set for it depending on difficulty chosen and also the races...

and of course, spawn the correct units and monitor recyclers etc..

after that my other modifications should be easy =]... its just the initial setup that is difficult...

ill be using the bzi scriptor btw... not fluent in anything else =[
Title: Re: making a new .dll
Post by: Sonic on December 28, 2007, 06:04:47 PM
The closest thing I've got to what you want would be my BZ2 Bench Test. You can get the script at: http://www.starfleetplatoon.com/users/sonic/bz2/dll_scripts/bz2benchtest.bzs

While it doesn't use AIPs, you can see how I grabed variables to decide what units to attack with, for both teams. I believe you can get the full map and stuff from bzscrap.
Title: Re: making a new .dll
Post by: Avatar on December 28, 2007, 06:28:42 PM
Well, my discussions with Natty over the years has given me a fairly decent understanding of how the DLL should work...

To select an AIP, certain conditions have to be met.  The standard naming convention for AIPs covers several stages of gameplay, from base building to initial attacks, to late game attacks, to 'siege mode'. 

Now, in Natty's case the conditions are simple.  All he does is have the DLL determine:

"What is the meanest thing the AI could do when the player does ________?"

So, getting too far from your base triggers the 'crush them completely' AIP.  Holing up in your base, otoh, triggers the 'death of 1000 archers' routine...

See?

So basically you'd determine conditions by doing things like watching the distance of the player from his Recy, the distance of the Player to the AI Recy, how many GT's he's got vs Turrets, that sort of thing. 

-Av-
Title: Re: making a new .dll
Post by: TheJamsh on December 28, 2007, 07:32:49 PM
the difficult bit really is getting the .dll to take the shell information when you select a map/race/AIP level

its for instant games, so if i decide i want to play as the scion against the AAN on a diffucult match, i ned it to spawn fvrecycpu, avrecy, avscout and fvscout probabaly...
Title: Re: making a new .dll
Post by: Sonic on December 29, 2007, 01:27:20 AM
Hehe, Avatar just reminded me what I ran into when I was modifying the MPI source code the other day under taunts.cpp...
"OK Natty, now what do I do?",

Conditions can be rather simple to do, just have a routine that runs checking various things like the distance of the nereast human controled unit to the enemy recycler. If its below 250, switch AIP to anti-siege. Or you could monitor the Enemy Recycler's health, if it gets below a certain value, switch plans and suprise the players.

I wrote up a quick Scriptor script (may have errors) that mimics somewhat the instant.dll with AIPs. Its just basic, you will have to do a good amount of editing to take in account races and what not, but it should get you started:
[routine,AIPExample,1,true]
SetPlan,"startup.aip",6
Wait,180
SETPLAN:
  ConsoleWord,"Anti-Siege Off"
  Set,SiegeCount,0
  RandJump,PLAN2,PLAN3 // Randomly select a 'normal' plan
PLAN1:
  SetPlan,"plan1.aip",6
  GoTo,ENDSETPLAN
PLAN2:
  SetPlan,"plan2.aip",6
  GoTo,ENDSETPLAN
PLAN3:
  SetPlan,"plan3.aip",6
ENDSETPLAN:
  Wait,1
  NearEnemy,human,EnemyRecycler
  IsODF,human,"ivscav" // We don't care about scavengers
  IfEQ,true,ENDSETPLAN
  DistObject,human,EnemyRecycler
  IfGT,250,RESETSIEGE
  Add,SiegeCount,1
  IfGT,45,ANTISIEGE // If a human has been nearby for about 45 seconds, kick Anti-Siege on
  GoTo,ENDSETPLAN
RESETSIEGE:
  Set,SiegeCount,0 // Zero out Counter
  GoTo,ENDSETPLAN
ANTISIEGE:
  ConsoleWord,"Anti-Siege Mode Initilized"
  SetPlan,"antisiege.aip",6
CHECKSIEGE:
  Wait,120 // Check Conditions every 2 minutes
  NearEnemy,human,EnemyRecycler
  DistObject,human,EnemyRecycler
  IfGT,250,SETPLAN // Turn Anti-Siege Off
  GoTo,CHECKSIEGE


Personally though, I like doing this stuff in C++ now...it can get alot more evil. >:D
// Check Enemy Recycler, when health reaches certain points do stuff
// Not recomended for games with Sanity installed...
void instantMission::RecyclerDefense()
{
  float RecyRatioH=GetHealth(enemy_recycler);
  Handle hTemp;
  Vector NewPos;
  int i;

  // Discharge Defense if Recycler takes enough damage
  if((bPkKiller) && (RecyRatioH < 0.75f)) {
    bPkKiller=false;
    SendPKs(true,true);
    NewPos=GetPositionNear(EnemyRecyPos,20.0f,30.0f);
    hTemp=BuildStartingVehicle(comp_team,CPUTeamRace,"*vservcpu","*vserv",NewPos);
    Service(hTemp,enemy_recycler);
    AddScrap(comp_team,30);
  }
  if((bSpiceDefense) && (RecyRatioH < 0.5f)) {
    bSpiceDefense=false;
    last_spiceattack=turn_counter;
    SendLacourSpices(true);
    for(i=0;i<3;i++) { // Create Service Trucks and heal
      NewPos=GetPositionNear(EnemyRecyPos,20.0f,30.0f);
      hTemp=BuildStartingVehicle(comp_team,CPUTeamRace,"*vservcpu","*vserv",NewPos);
      SetMaxHealth(hTemp,21000); // Make it not easy to blow these guys up
      SetCurHealth(hTemp,21000);
      Service(hTemp,enemy_recycler);
    }
    if(bReinforcements)
      Reinforcements(false);
    if(mySide==1) // Make more of a distraction to get 'em off our backs!
      FuryRun();
    else
      SiegeTankRun();
    AddScrap(comp_team,60);
    AddHealth(enemy_recycler,3000); // Damnit! Seriously, who sealed the Nine Tails inside their Recycler?
  }
  if((bFinalLineofDefense) && (RecyRatioH < 0.15f)) { //Oh mighty Cursix, HELP ME!
    bFinalLineofDefense=false; // Note, we get more than one now! >:D
    last_finalline=turn_counter;
    DoTaunt(TAUNTS_FinalLine);
    PrintConsoleMessage("ATTENTION: Final Line of Defense has been breached!");
    if(bReinforcements) // Only because if it was off, count would be 1, meaning they would SUCK!
      Reinforcements(false);
    SendPKs(true,false);
    SendLacourSpices(false);
    if(mySide==1)
      FuryRun();
    else
      SiegeTankRun();
    AddHealth(enemy_recycler,21000); // Hey, who gave the CPU access to the Support Symbology Package?

    // All Evil Credit goes to CmptrWz.
    Handle hndPlayer;
    Vector hisSpeed;
    float rnd=GetRandomFloat(1.0f);
    for(i=0; i<MAX_TEAMS; i++) {
      hndPlayer=GetPlayerHandle(i);
      if(hndPlayer) {
        if(GetTeamNum(hndPlayer) != strat_team) {
          // We have a Player! Screw with them!
          if((!IsPerson(hndPlayer)) && (rnd > 0.5f)) // About 50% chance that player ejects
            EjectPilot(hndPlayer);
          // OK, so this part was my idea -Sonic
          hndPlayer=GetPlayerHandle(i); // Re-Grab Player as they may have ejected
          if(hndPlayer && IsAround(hndPlayer)) { // Make sure we have an object
            hisSpeed=GetVelocity(hndPlayer);
            hisSpeed.x-=111.1f;
            hisSpeed.y+=150.0f;
            hisSpeed.z+=333.3f;
            SetVelocity(hndPlayer,hisSpeed); // How high will they go?
          }
        }
      }
    }

    // Drop a service truck and let it service what needs serviced
    NewPos=GetPositionNear(EnemyRecyPos,25.0f,30.0f);
    hTemp=BuildStartingVehicle(comp_team,CPUTeamRace,"*vservcpu","*vserv",NewPos);
    SetMaxHealth(hTemp,21000);
    SetCurHealth(hTemp,21000);

    // We're most likely thristy at this point, lets have a drink!
    AddScrap(strat_team,-120);
    AddScrap(comp_team,120);
  }

  // Recharge Defense if Recycler Heals Enough
  if((!bPkKiller) && (RecyRatioH > 0.95f))
    bPkKiller=true;
  if((!bSpiceDefense) && (RecyRatioH > 0.7f) && (turn_counter > (last_spiceattack + (180 * m_GameTPS))))
    bSpiceDefense=true;

  // We Recharge Final Line of Defense 15 Minutes after it was triggered last
  if((!bFinalLineofDefense) && (turn_counter > (last_finalline + (900 * m_GameTPS))))
    bFinalLineofDefense=true;
}
Title: Re: making a new .dll
Post by: OvermindDL1 on December 29, 2007, 01:40:04 AM
-120 scrap to the human team if the AI recy is less then 15% health, the frick?
Title: Re: making a new .dll
Post by: Sonic on December 29, 2007, 01:50:38 AM
When the humans have insane custom assets including but not limited to a Recycler with 80 scrap storage, I think the AI needs a break. ;)
Title: Re: making a new .dll
Post by: Avatar on December 29, 2007, 05:47:14 AM
I think the heart of what Jamsh is asking is something I've asked before and never gotten an answer to...

How can a Scriptor-made DLL read the buttons selected at the start of a match?

In my case I wanted to find out if the Scriptor could read the Game Difficulty setting, so I could adjust for Easy/Medium/Hard settings.

Never did figure out how to do that...

-Av-
Title: Re: making a new .dll
Post by: TheJamsh on December 29, 2007, 06:14:57 AM
thats exactly it... conditions i can do... getting it to read the setup information i cant get it to do...

lizard added a new .dll to his fleshstorm mod i think which enabled you to pick the races in match much like fe for 1.2
Title: Re: making a new .dll
Post by: Lizard on December 29, 2007, 06:15:04 AM
Quote from: Avatar on December 29, 2007, 05:47:14 AM
I think the heart of what Jamsh is asking is something I've asked before and never gotten an answer to...

How can a Scriptor-made DLL read the buttons selected at the start of a match?

In my case I wanted to find out if the Scriptor could read the Game Difficulty setting, so I could adjust for Easy/Medium/Hard settings.

Never did figure out how to do that...

-Av-


I never figured that out either, it may be one of the limitations of the scriptor, there's nothing to stop you having a popup panel that appears once you launch the mission with options on it like in FleshStorm, FE and even G66, you can pretty much have any options you like on one of those from difficulty settings to race selections and a whole lot more besides. 
Title: Re: making a new .dll
Post by: Sonic on December 29, 2007, 06:19:45 PM
You should be able to grab information from the shell before launch if the shell stores things in the right place. You would grab the information the same way I did in the bench test.

  IFaceGetInt,"options.instant.int1"
  StoreResult,Difficulty
  ...
  Add,Difficulty,0
  IfEQ,0,EASY
  IfEQ,1,MEDIUM
  IfEQ,2,HARD
EASY:
  ...
  GoTo,ENDDIFFICULTY
MEDIUM:
  ...
  GoTo,ENDDIFFICULTY
HARD:
  ...
ENDDIFFICULTY:
  ...
Title: Re: making a new .dll
Post by: Avatar on December 29, 2007, 06:34:47 PM
Is that actual code?  (other than 'goto' needs to be 'jumpto')  To determine difficulty?  That would be awesome, although it would also probably make me go back and redo all of the BZC Scripts...  :)

It would be worth it, though, to be able to select the mission difficulty.  It's such a tough thing making a decent mission given how wide a range of players there are. 

***

Trying it I guess it's not complete...  it comes up 'easy' no matter what I select.

So, it's an example...  how do we find out the actual iface entry to look for?  When I pull up options the console spams 'page 0' and 'selected 0'...  not sure what that means. 

We're very close, so thanks for the nudge in the right direction... now to nail it down to the actual entry...

***

Looking over BZESCAPE_PLAY.CFG I find:

//Easy
UseVar("options.play.difficulty");
Value(0);

//Medium
Value(1);

//Hard
Value(2);

Off to try that...

***

YEEEEHA!

Good thing Sonic's not here 'cause I'd kiss him right on the lips...    :roll:

Here you go, the code to read the selected difficulty:

DoAgain:
IFaceGetInt,"options.play.difficulty"
  StoreResult,Difficulty

  Add,Difficulty,0
  IfEQ,0,EASY
  IfEQ,1,MEDIUM
  IfEQ,2,HARD
EASY:
  ConsoleWord,"Easy"
  JumpTo,ENDDIFFICULTY
MEDIUM:
  ConsoleWord,"Medium"
  JumpTo,ENDDIFFICULTY
HARD:
  ConsoleWord,"Hard"
ENDDIFFICULTY:

Wait,3
Jumpto,DoAgain

The jumpto,doagain bit is just for testing, so I can watch it.  Awesome...  this explains a lot, and now pretty much any difficulty setting can be read by a Scriptor-built script.

That's been bugging me for years, literally.

Thanks, Sonic!  Very cool...

-Av-
Title: Re: making a new .dll
Post by: TheJamsh on December 29, 2007, 07:16:06 PM
very good!

now we jsut need to get it to read race type, AIP plans player respawn and the like and volia lol!
Title: Re: making a new .dll
Post by: Sonic on December 29, 2007, 07:20:47 PM
Yea, the options.instant.int1 was just an example you could use if you made your own CFG for your instant map. Glad I could be of help.
Title: Re: making a new .dll
Post by: Warfreak on December 29, 2007, 07:31:56 PM
Racetype works JUST LIKE DIFFICULTY!!!  :-D

I'm gonna use the My .cfg (which is bassed off of the FE chaos maps.cfg, yes, i cant remember the name of the exact .cfg) as an example (based off of Av's one as im too lazy to pull up the real one):

DoOnce:
IFaceGetInt,"race1.count"
 StoreResult,race_player

 Add,race_player,0
 IfEQ,0,ISDF
 IfEQ,1,HADEAN
 IfEQ,2,RODIAN
EASY:
 ConsoleWord,"ISDF in Battle"
 JumpTo,ENDDIFFICULTY
MEDIUM:
 ConsoleWord,"Hadean in Battle"
 JumpTo,ENDDIFFICULTY
HARD:
 ConsoleWord,"Rodian in Battle"
ENDDIFFICULTY:

Wait,3
Jumpto,DoAgain

DoAgain:
IFaceGetInt,"race2.count"
 StoreResult,race_cpu

 Add,race_cpu,0
 IfEQ,0,ISDF
 IfEQ,1,HADEAN
 IfEQ,2,RODIAN
EASY:
 ConsoleWord,"ISDF in Battle"
 JumpTo,ENDDIFFICULTY
MEDIUM:
 ConsoleWord,"Hadean in Battle"
 JumpTo,ENDDIFFICULTY
HARD:
 ConsoleWord,"Rodian in Battle"
ENDDIFFICULTY:

Wait,3
Jumpto,Setup_player

Setup_player:
//inset your spawning lines here according to race selection

Setup_cpu:
//again, place lines here.

That is basically how thats done.
Title: Re: making a new .dll
Post by: Avatar on December 30, 2007, 05:56:51 AM
Very cool...   :)

I personally am shooting for NOT using an in game console, as I'd rather just use whatever the player's normal settings are.  Then again I don't need anything much extra for the stock races.

The 'Ancients', OTOH, might need some unusual options set...  then there's a few options for MP that I haven't dealt with such as the game ending when a life limit is reached...

-Av-
Title: Re: making a new .dll
Post by: TheJamsh on December 30, 2007, 10:53:48 AM
im aiming for the same as avatar, No in game console...
Title: Re: making a new .dll
Post by: Sonic on December 30, 2007, 11:59:19 PM
"options.instant.<bla>" is used for Instant Action Missions while "network.session.<blah>" is used for Multiplayer. IA maps are easy when it comes to variables, however, multiplayer variables require that the variable is the same on both sides. An interesting thing I noticed was network.session.svar60 was not traversing the network. So while the host saw svar60 as "blah", the clients saw it as "" which caused rsyncs when ever the DLL evaluated what svar60 was. Because of this, it probobly is a good pratice in 1.3 to do all your variables in the BZ2 shell BEFORE the game launch instead of launching a shell in game.
Title: Re: making a new .dll
Post by: OvermindDL1 on December 31, 2007, 08:01:47 AM
Or just have the host dll send it to the client dll's so they all stay in sync fine that way, just need to take into account network delay.
Title: Re: making a new .dll
Post by: GSH on January 02, 2008, 01:42:02 AM
BZ2 doesn't propagate svar/ivar changes after the game starts.

-- GSH
Title: Re: making a new .dll
Post by: OvermindDL1 on January 02, 2008, 01:56:28 AM
Functions were added in one of the earlier 1.3pb dll's that allow the host to send information to a client.  Just make sure to take into account latency so everything stays perfectly timed, and so forth...