[ZScript] Scheduler

Post your example zscripts/ACS scripts/etc here.

[ZScript] Scheduler

Postby Gustavo6046 » Sat Dec 23, 2017 9:38 am

Good afternoon. I have been doing a bot in ZScript (ZetaBot), and I found out that, to make sure it'd work with weapon switching (weap.Use() can't be followed immediately by FireWeapon() or FireWeaponAlt() if I recall correctly), I had to create a Scheduler. It is basically a class that will check for a condition every tick (based on a ScheduleChecker or a WeaponChecker), and, if this condition is met, it will set its state to a done state. Its state can be polled every tick (it calls Destroy() on itself if the state is SS_DONE). I believe this will make it easier to create sequence of actions in a Thinker, where actor states are for some reason not yet supported. (I know, they are called actor states, but Thinkers could have some sort of finite state machine too, like invisible states, idk!)

Why are they going to be used by ZetaBots? Because otherwise they might not fire at all. They do have weapon rating code (it's rather bad, but then blame the actor state API - I wanted to get the amount of times that A_FireProjectile/A_FireBullets/etc are called, and their projectile classes, as part of an equation!), but you know how it's difficult to create a Thinker to control ("possess") a PlayerPawn - especially with weapon handling!

So Schedulers were made to make the job slightly simpler. I hope you enjoy them as well :)

TL;DR something inspired by JavaScript Promises.

Code: Select allExpand view
class ScheduleChecker : Thinker
{
   bool bDone;
   
   void BeginPlay()
   {
      bDone = false;
   }
   
   void fire()
   {
      bDone = true;
   }
}

class WeaponChecker : ScheduleChecker
{
   PlayerPawn __p;
   Weapon __w;

   void link(PlayerPawn other, Weapon weap)
   {
      __p = other;
      __w = weap;
   }
   
   static WeaponChecker create(PlayerPawn other, Weapon weap)
   {
      let res = new("WeaponChecker");
      res.link(other, weap);
      
      return res;
   }
   
   override void Tick()
   {
      Super.Tick();
      
      if ( !bDone && __p != null && __p.player.ReadyWeapon == __w )
         fire();
   }
}

class Scheduler : Thinker
{
   enum ScheduleState
   {
      SS_PENDING,
      SS_RUNNING,
      SS_DONE
   };
   
   ScheduleState __s;
   ScheduleChecker checker;
   
   void BeginPlay()
   {
      __s = SS_PENDING;
   }
   
   static Scheduler create(ScheduleChecker checker, bool bAutoStart)
   {
      let res = new("Scheduler");
      res.checker = checker;
      
      if ( bAutoStart )
         res.__s = SS_RUNNING;
         
      return res;
   }
   
   ScheduleState pollState()
   {
      if ( __s == SS_DONE )
         Destroy();
         
      return __s;
   }
   
   override void Tick()
   {
      Super.Tick();
   
      if ( __s != SS_RUNNING )
         return;
         
      if ( checker.bDone )
         __s = SS_DONE;
   }
}


EDIT: added recent changes
User avatar
Gustavo6046
 
Joined: 13 May 2017
Location: In an urban area in Brazil.
Discord: 9009

Return to Script Library

Who is online

Users browsing this forum: No registered users and 1 guest