• Welcome to Battlezone Universe.
 

News:

Welcome to the BZU Archive dated December 24, 2009. Topics and posts are in read-only mode. Those with accounts will be able to login and browse anything the account had access granted to at the time. No changes to permissions will be made to be given access to particular content. If you have any questions, please reach out to squirrelof09/Rapazzini.

Main Menu

The Scriptor, Mission Difficulty, and you...

Started by Avatar, January 21, 2008, 12:56:56 PM

Previous topic - Next topic

Avatar

I personally think the Scriptor and/or DLL creation could use their own sub-boards.  I know there's been a lot of help given here and there, but it would be nice to have it all in one place.

Anyway, as a contribution to anyone wanting to learn more about the phenomenally easy to use DLL Scriptor by BS-er, here's some code that reads the difficulty level the Player has selected in the Options/Play screen and runs different code depending on that choice.  This is something I'd been trying to figure out for some time and am now incorporating into BZClassic to make the 'Hard' setting take you beyond the original BZ1 missions.

To read the Difficulty setting:

IFaceGetInt,"options.instant.int1"   //reads the difficulty they chose
  StoreResult,Difficulty                  //stores the result in the variable "Difficulty"

  Add,Difficulty,0                         //The Scriptor can't compare two values directly (no "if A = B")
  IfEQ,0,EASY                             //"Easy" reads as zero, if Difficulty + 0 = 0 Goto EASY
  IfEQ,1,MEDIUM                         //"Medium" reads as one, if Difficulty + 0 = 1 Goto MEDIUM
  IfEQ,2,HARD                             //"Hard" reads as two, if Difficulty + 0 = 2 Goto HARD

EASY:       //Go here if they chose '0' or 'Easy'.
  //place your code here, like this line that makes a Warrior
   createp,warrior1,"fvtank",5,"spawnpoint1"
             
  GoTo,ENDDIFFICULTY     //When done with your code jump over the rest

MEDIUM:    //Go here if they chose '1' or 'Medium'
  //again, your code for medium goes here, like making TWO Warriors
  createp,warrior1,"fvtank",5,"spawnpoint1"
  createp,warrior2,"fvtank",5,"spawnpoint2"

  GoTo,ENDDIFFICULTY    //Again, you have to jump over the rest when done

HARD:
  //your code for hard goes here, like making THREE Warriors
  createp,warrior1,"fvtank",5,"spawnpoint1"
  createp,warrior2,"fvtank",5,"spawnpoint2"
  createp,warrior3,"fvtank",5,"spawnpoint3"

ENDDIFFICULTY:    //and here we are, all done.


Now, if all you were doing was making warriors you can condense it all down:

IFaceGetInt,"options.instant.int1"   //reads the difficulty they chose
  StoreResult,Difficulty                  //stores the result in the variable "Difficulty"

  Add,Difficulty,0                         //The Scriptor can't compare two values directly (no "if A = B")
  IfEQ,0,EASY                             //"Easy" reads as zero, if Difficulty + 0 = 0 Goto EASY
  IfEQ,1,MEDIUM                         //"Medium" reads as one, if Difficulty + 0 = 1 Goto MEDIUM
  IfEQ,2,HARD                             //"Hard" reads as two, if Difficulty + 0 = 2 Goto HARD

HARD:   //'hard' will make three warriors
  createp,warrior3,"fvtank",5,"spawnpoint3"
MEDIUM: //'medium' will make two warriors
  createp,warrior2,"fvtank",5,"spawnpoint2"
EASY:  //'easy' will make one warrior
  createp,warrior1,"fvtank",5,"spawnpoint1"

//and here we are, all done.


Keep in mind that the DLL is run progressively, and the setting read at the time that the code is run.  That means with this code they can play on 'Hard' until they cry, and then drop down to 'Easy' to get through the tough part, going back to 'Hard' again to say they made it to the end on 'Hard'...   :)

-Av-



OvermindDL1

#1
Or in my Python scriptor:
# Direct code:
difficulty = IFace_GetInteger("options.instant.int1")
if difficulty==0:
    # Do easy
elif difficulty==1
    # Do medium
elif difficulty==2
    # Do Hard

# Could also define these somewhere in the main script area:
Easy = 0
Medium = 1
Hard = 2

# So you can do this instead (more readable):
difficulty = IFace_GetInteger("options.instant.int1")
if difficulty is Easy: # Could still do difficulty==EASY is so inclined, but this is more readable and appropriate for this case
    # Do easy
elif difficulty is Medium
    # Do medium
elif difficulty is Hard
    # Do Hard


Or in C++:
const int difficulty = IFace_GetInteger("options.instant.int1")
if(difficulty==0)
{
    // Do Easy
}
else if(difficulty==1)
{
    // Do Medium
}
else if(difficulty==2)
{
    // Do Hard
}

// Or to be more readable, put this somewhere in a main section or header or what-not (and yes, for any of you real programmers, I would normally put constants, in both C++ and Python all in caps, but this is easier to look at for non-programmers):
const int Easy = 0;
const int Medium = 1;
const int Hard = 2;

// Then this:
const int difficulty = IFace_GetInteger("options.instant.int1")
if(difficulty==Easy)
{
    // Do Easy
}
else if(difficulty==Medium)
{
    // Do Medium
}
else if(difficulty==Hard)
{
    // Do Hard
}

Lizard

this is another thread that could do with being stickied , but we have so many stickies up there already I'm a bit reluctant to add another one .......

OvermindDL1

Should probably add it to a Wiki, this is not really the kind of stuff to belong in a forum post. :)

Avatar

First off, I don't mean any slight to your Scriptor OM, it's just the BSer was there first and his is a bit more english-intuitive, or at least IMHO easier for a non-programmer to pick up and do something with.  It's also very well documented and Sonic has made a ton of examples available to boot.

So not to leave you out in the cold here, and it's excellent that you post a 'translation' to both your Python and VC++.  Makes this sort of a 'Rosetta Stone' for scripting...  :)

As to a Wiki that would be cool.  I'd love to see examples of code posted, as well as some place people could post code they need help with OR just questions and such.

-Av-

Sonic

I'll pass the thought of having a DLL Scriptor Forum to CmptrWz. I would say thought it won't happen till the site is moved to the new server.
"Linux is user friendly...
...it's just very selective about who its friends are."

Red Devil

 I say bite the bullet and learn C++.  Well worth it.
What box???

Sonic

Quote from: Red Devil on January 21, 2008, 05:05:45 PM
I say bite the bullet and learn C++.  Well worth it.

I dunno, C++ works great for things like MPIs, but the DLL Scriptor provides lineage which is great for story based missions. I find it alot easier to write a single player mission in the scriptor when I'm worried about having the player do x than y than z than to write a C++ DLL. I find it easier in C++ however to do things like do x every 10 minutes, check y every run, suprise the player when z happens.
"Linux is user friendly...
...it's just very selective about who its friends are."

bigbadbogie

without the dll scriptor i bet that many mods would never have been made - fleshstorm and FE would be pipedreams

i looked at some c++ coding a while ago and vowed to never, ever learn how to do that - because my life would vanish
Others would merely say it was good humour.


My BZ2 mods:

QF2: Essence to a Thief - Development is underway.

Fleshstorm 2: The Harvest - Released on the 6th of November 2009. Got to www.bz2md.com for details.

QF Mod - My first mod, finished over a year ago. It can be found on BZ2MD.com

Nielk1

#9
Personaly that C++ looks more at home to me...
It could use adding to the BZU wiki (whereever it is). My BZWIKI is not so technicly minded ATM, it is more conserned about story (that and I'm moving sites). :roll:

Click on the image...

OvermindDL1

Let's see, with my python version (mostly going to Sonic there), mine has linearity (you can even Sleep(time) and it will pause that tasklet, can make it very linear, not to mention tasklets are vastly useful in simplifying *so* much code).  The code tends to be a great deal shorter then BS-er's scriptor and C++ (while being more readable in my opinion, I can give examples if you give me large swathes of scriptor code for me to convert :) ).

And doing things every so often, in my scriptor is like this:

    def DoEveryTenMinutes():
        while True:
            AddToMessagesBox("This is sent once every ten minutes"
            Sleep(10*60*10) # 10 ticks in a second, 60 seconds in a minute, for 10 minutes, could just write 6000, I could even make conversions functions so you could write something like:   Sleep(MinutesToTicks(10))

    def RunEveryTick()
        while True:
            AddToMessagesBox("This will spam your message box every single tick (ten times a second)")
            Sleep()

    # This decorator does not exist, but I could make it in, oh, a few seconds...
    @RunWhenIsBuilt(ODF="UberTank", Team=HumanTeam)
    def UberTankBuiltByHumans(uberTank):
        while uberTank: # While uberTank is alive in other words), could also do while uberTank.IsAlive():
            BuildObject("UberTankKiller", ComputerTeam, UberTankKillerSpawnPoint).Attack(uberTank, 1000) # Focusing on killing the ubertank, at the expense of all else
            Sleep(10*60) # Wait 60 seconds, then retest if uberTank is alive, if so, it will build another killer, if not, then the killers will be idle and soon be picked up by the idle dispatcher, would also be simple to keep a list of them and send them off to do something else once the uberTank is dead)

    @RunWhenPlayerDies(Team=HumanTeam)
    def PlayerDied(player):
        FailMission(100, "PlayerDiedLostMessage.txt")

    @RunWhenIsDestroyed(ODF="UberTank", Team=HumanTeam)
    def UberTankDied(uberTank):
        FailMission(100, "UberTankDiedLostMessage.txt")

    @RunWhenIsDestroyed(ODF="AiRecy", Team=ComputerTeam)
    def ComputerRecyclerDied(recy):
        SucceedMission(100, "ComputerKilledWinMessage.txt")

    def SomethingLinearForPlayerToDo():
        player = GetLocalPlayer()
        uberTankFactory = GetUberTankFactory()

        AddObjective("Goto Uber-Tank Factory", WHITE)
        SetObjectiveOn(uberTankFactory)
        while not player.IsWithin(uberTankFactory, 50):
            Sleep()

        ClearObjectives()
        AddObjective("Goto Uber-Tank Factory", GREEN)
        AddObjective("Slaughter the enemy before they slaughter your Uber-Tank", WHITE)

        SetBestGroup(BuildObject("UberTank", HumanTeam, uberTankFactory))

        AddToMessagesBox("Computer: GAGH, I WILL KILL YOU FOR THAT!", RGB(255, 64, 64))


And yes, those decorated functions (when something dies and so forth, I really should make those, would be easy, and it is powerful as seen... hmm... next version perhaps) can be turned on or off at will, but they are on by default. and not all parameters are necessary, for example if Team is omitted then it will be called anytime anyone builds/kills one, regardless of Team, and could be other options too.

How would something like this work in the scriptor, I know it would be pretty simple too for 'some' of those functions, and in C++ pretty much all of that is... well... impossible as is, would need a lot of code to set things up and so forth, or make real threads with locks.

Red Devil

 You slay me, dude.  I can see you and Nathan and Ken sitting on the back porch in your old age enjoying a good sherry reminiscing about the classes you've built and the bad pointers you found.
What box???

OvermindDL1

Programming is life. :)
Literally though, you should hear me when someone asks what I have been up to coding recently (usually they are relatively new around me and just know I 'program', but do not know how involved I get), I will start and go for hours if I am not stopped, talking about implementation details I discovered were useful, little bugs I ran into, etc... etc...  I am not normally asked again. :p

bigbadbogie

Others would merely say it was good humour.


My BZ2 mods:

QF2: Essence to a Thief - Development is underway.

Fleshstorm 2: The Harvest - Released on the 6th of November 2009. Got to www.bz2md.com for details.

QF Mod - My first mod, finished over a year ago. It can be found on BZ2MD.com

OvermindDL1