Exemple #1
0
int CChitemDlg::check_or_scan_trigger(const trigger *tpoi, int checkflags, int check_or_scan, int bcnt)
{
  CString area;
  int ret, gret;

  gret=0;
  if((checkflags&0xff00)==0xff00)
  {
    if(checkflags&1) area=CString(tpoi->var2)+tpoi->var1;
    else area=CString(tpoi->var1)+tpoi->var2;
    ret=store_variable(area, ADD_VAR, tpoi->opcode, TRIGGER|check_or_scan, bcnt);
    gret|=ret;
  }
  else
  {
    varname2=tpoi->var2;
    ret=store_variable(tpoi->var1, checkflags, tpoi->opcode, TRIGGER|check_or_scan, bcnt);
    gret|=ret;
    ret=store_variable(tpoi->var2, checkflags>>8, tpoi->opcode, TRIGGER|check_or_scan, bcnt);
    gret|=ret;
  }
  if(check_or_scan==SCANNING) return gret;

  //don't store this if just scanning, these are checked, but never SET, so they must be invalid if used alone
  if (tpoi->trobj.var[0])
  {
    ret = store_variable(tpoi->trobj.var, ADD_DEAD, 0, OBJECT|TRIGGER|check_or_scan, bcnt);
    gret |= ret;
  }

  ret=check_integers(&tpoi->bytes[0], checkflags, tpoi->opcode, TRIGGER|check_or_scan, bcnt);
  gret|=ret;
  return gret;
}
Exemple #2
0
int CChitemDlg::check_or_scan_action(const action *apoi, int checkflags, int check_or_scan, int bcnt)
{
  CString area;
  int i;
  int ret, gret;
  
  gret=0;
  if((checkflags&0xff00)==0xff00)
  {
    if(checkflags&1) area=CString(apoi->var2)+apoi->var1;
    else area=CString(apoi->var1)+apoi->var2;
    ret=store_variable(area, ADD_VAR, apoi->opcode, ACTION|check_or_scan, bcnt);
    gret|=ret;
  }
  else
  {
    varname2=apoi->var2;
    ret=store_variable(apoi->var1, checkflags, apoi->opcode, ACTION|check_or_scan, bcnt);
    gret|=ret;
    ret=store_variable(apoi->var2, checkflags>>8, apoi->opcode, ACTION|check_or_scan, bcnt);
    gret|=ret;
  }

  //don't store these if just scanning, it is checked, but never SET, so it must be invalid if used alone
  for(i=0;i<3;i++)
  {
    if (check_or_scan==SCANNING && !i) continue; //the override variable is never written, so it shouldn't be stored here
    store_variable(apoi->obj[i].var, ADD_DEAD, i, OBJECT|ACTION|check_or_scan, bcnt);
  }
  if(check_or_scan==SCANNING) return gret;

  ret=check_integers(&apoi->bytes[0], checkflags, apoi->opcode, ACTION|check_or_scan, bcnt);
  gret|=ret;
  return gret;
}
Exemple #3
0
void store(uint16_t v)
{
  store_variable(BYTE(pc++), v);
}
Exemple #4
0
int CChitemDlg::check_script(int check_or_scan) //scans for variables
{
  int ret, gret;
  int bcnt, tcnt, rcnt, acnt;
  block *bpoi;
  trigger *tpoi;
  response *rpoi;
  action *apoi;
  int num_or;
  int checkflags;
  CString area;
  journal_type journal;
  int opcode;
  int i;

  gret=0;
  if(!the_script.blockcount)
  {
    gret=-1;
    log("Empty script!");
  }
  for(bcnt=0;bcnt<the_script.blockcount; bcnt++)
  {
    bpoi=&the_script.blocks[bcnt];
    if(!bpoi->triggercount && (check_or_scan!=SCANNING) )
    {
      gret=-1;
      log("No trigger in block #%d",bcnt+1);
    }
    //triggers using variables
    num_or=0;
    opcode=0; //initialize opcode to non-TR_FALSE
    
    if(check_or_scan!=JOURNAL) //triggers don't have journals
    {
      for(tcnt=0;tcnt<bpoi->triggercount; tcnt++)
      {
        tpoi=&bpoi->triggers[tcnt];
        opcode=tpoi->opcode&0x1fff;
        if(check_or_scan==CHECKING)
        {
          if((opcode>MAX_TRIGGER) || !trigger_defs[opcode].GetLength())
          {
            gret=-1;
            log("Invalid trigger: %d (%04x) in block #%d trigger #%d",tpoi->opcode, tpoi->opcode,bcnt+1,tcnt+1);
            continue;
          }
          if(pst_compatible_var()) continue;
          if(opcode==TR_OR)
          {
            if(num_or)
            {
              gret=-1;
              log("Bad OR count in block #%d trigger #%d",bcnt+1,tcnt+1);
            }
            num_or=tpoi->bytes[0];
            if (num_or<2 && check_or_scan!=SCANNING)
            {
              gret=-1;
              log("Incorrect or redundant Or() in block #%d trigger #%d", bcnt+1, tcnt+1);
            }
          }
          else if(num_or) num_or--;
        }
        
        checkflags=handle_trigger(tpoi->opcode);
        // not only death variable but: waypoints, triggers, doors etc
        if(store_variable(tpoi->trobj.var, CHECK_DEAD2|(checkflags&0xffff0000),0,OBJECT|TRIGGER|check_or_scan,bcnt))
        {
          log(resolve_scriptelement(opcode, TRIGGER, bcnt));
        }
        if((checkflags&0xff00)==0xff00)
        {
          if(checkflags&1) area=CString(tpoi->var2)+tpoi->var1;
          else area=CString(tpoi->var1)+tpoi->var2;
          ret=store_variable(area, ADD_VAR, tpoi->opcode, TRIGGER|check_or_scan, bcnt);
          gret|=ret;
        }
        else
        {
          varname2=tpoi->var2;
          ret=store_variable(tpoi->var1, checkflags, tpoi->opcode, TRIGGER|check_or_scan, bcnt);
          gret|=ret;
          ret=store_variable(tpoi->var2, checkflags>>8, tpoi->opcode, TRIGGER|check_or_scan, bcnt);
          gret|=ret;
        }
        if(check_or_scan==CHECKING)
        {
          ret=check_integers(&tpoi->bytes[0], checkflags, tpoi->opcode, TRIGGER|check_or_scan, bcnt);
          gret|=ret;
        }
      }
      if(check_or_scan==CHECKING)
      {
        if(num_or)
        {
          gret=-1;
          log("Bad OR count in block #%d trigger #%d",bcnt+1,tcnt);
        }
        
        if(!bpoi->responsecount )
        {
          log("No response in block #%d",bcnt+1);
        }
      }
    }

    for(rcnt=0;rcnt<bpoi->responsecount; rcnt++)
    {
      rpoi=&bpoi->responses[rcnt];      
    //if last opcode is False() then we don't care about the empty response
      if(opcode!=TR_FALSE && !rpoi->actioncount && (check_or_scan==CHECKING) )
      {
        gret=-1;
        log("No action in block #%d response #%d",bcnt+1,rcnt+1);
      }
      //actions using variables
      num_or=0;
      for(acnt=0;acnt<rpoi->actioncount; acnt++)
      {
        apoi=&rpoi->actions[acnt];
        // not only death variable but: waypoints, triggers, doors etc
        
        for(i=0;i<3;i++)
        {
          if(store_variable(apoi->obj[i].var, CHECK_DEAD2|(0xffff0000&handle_action(apoi->opcode)),i,OBJECT|ACTION|check_or_scan,bcnt))
          {
            log("%s in response #%d",resolve_scriptelement(apoi->opcode, ACTION, acnt), rcnt+1);
          }
        }        

        if(check_or_scan==JOURNAL)
        {
          switch(apoi->opcode)
          {
            //this is a solved journal entry
          case AC_REMOVE_JOURNAL_IWD:case AC_QUESTDONE_IWD:
            if(has_xpvar())
            {
              journal.type=0;
              journals.Lookup(apoi->bytes[0], journal);
              journal.string="";
              journal.type|=HAS_SOLVED;
              journals[apoi->bytes[0]]=journal;
            }
            break;
          case AC_REMOVE_JOURNAL_BG: case AC_QUESTDONE_BG:
            if(!has_xpvar())
            {
              journal.type=0;
              journals.Lookup(apoi->bytes[0], journal);
              journal.string="";
              journal.type|=HAS_SOLVED;
              journals[apoi->bytes[0]]=journal;
            }
            break;
          case AC_ADD_JOURNAL:
            
            //this is an undone quest journal entry
            if(has_xpvar() || (apoi->bytes[3]==JT_QUEST))
            {
              if(journals.Lookup(apoi->bytes[0],journal))
              {
                if(!journal.string.IsEmpty())
                {
                  if (journal.string.Find(itemname)<0)
                  {
                    journal.string+=", "+itemname;
                  }
                  journal.type|=HAS_QUEST;
                  journals[apoi->bytes[0]]=journal;
                }
              }
              else
              {
                journal.string=itemname;
                journal.type=HAS_QUEST;
                journals[apoi->bytes[0]]=journal;
              }
            }
            else
            {
              if (apoi->bytes[3]==JT_DONE)
              {
                journal.type=0;
                journals.Lookup(apoi->bytes[0], journal);
                journal.string="";
                journal.type|=HAS_SOLVED;
                journals[apoi->bytes[0]]=journal;
              }
            }
            break;
          }
          
          continue;
        }
        if((apoi->opcode>MAX_ACTION) || !action_defs[apoi->opcode].GetLength())
        {
          gret=-1;
          log("Invalid action: %d in block #%d response #%d action #%d",apoi->opcode,bcnt+1, rcnt+1, acnt+1);
          continue;
        }
        checkflags=handle_action(apoi->opcode);
        if((checkflags&0xff00)==0xff00)
        {
          if(checkflags&1) area=CString(apoi->var2)+apoi->var1;
          else area=CString(apoi->var1)+apoi->var2;
          ret=store_variable(area, ADD_VAR, apoi->opcode, ACTION|check_or_scan, bcnt);
          gret|=ret;
        }
        else
        {
          varname2=apoi->var2;
          ret=store_variable(apoi->var1, checkflags, apoi->opcode, ACTION|check_or_scan, bcnt);
          gret|=ret;
          ret=store_variable(apoi->var2, checkflags>>8, apoi->opcode, ACTION|check_or_scan, bcnt);
          gret|=ret;
        }
        if(check_or_scan==CHECKING)
        {
          ret=check_integers(apoi->bytes, checkflags, apoi->opcode, ACTION|check_or_scan, bcnt);
          gret|=ret;
          if(chkflg&NOCUT) continue;
          if(apoi->opcode==AC_STARTCUT)
          {            
            if(num_or!=AC_STCUTMD)
            {
              log("StartCutScene() without StartCutSceneMode() in block #%d response #%d action #%d", bcnt+1,rcnt+1,acnt+1);
              gret|=1;
            }
          }
          if((apoi->opcode==AC_STCUTMD) || (apoi->opcode==AC_STARTCUT) || (apoi->opcode==AC_CLRACT) || (apoi->opcode==AC_CLRALLACT)) num_or=apoi->opcode;
        }
      }
    }
  }  
  return gret;
}