Example #1
0
// Scripts that always start immediately at level load.
void Map::ACS_StartOpenScript(acs_script_t *s)
{
  CONS_Printf("Starting an opening ACS (script %d)\n", s->number);

  acs_t *script = new acs_t(s);
  script->delay = TICRATE; // Give a second for the Map to get spawned.

  AddThinker(script);
}
VThinker* VLevel::SpawnThinker(VClass* AClass, const TVec& AOrigin,
	const TAVec& AAngles, mthing_t* mthing, bool AllowReplace)
{
	guard(VLevel::SpawnThinker);
	VClass* Class = AllowReplace ? AClass->GetReplacement() : AClass;
	VThinker* Ret = (VThinker*)StaticSpawnObject(Class);
	AddThinker(Ret);

	if (IsForServer() && Class->IsChildOf(VEntity::StaticClass()))
	{
		((VEntity*)Ret)->Origin = AOrigin;
		((VEntity*)Ret)->Angles = AAngles;
		((VEntity*)Ret)->eventOnMapSpawn(mthing);
		if (LevelInfo->LevelInfoFlags2 & VLevelInfo::LIF2_BegunPlay)
		{
			((VEntity*)Ret)->eventBeginPlay();
		}
	}
	return Ret;
	unguard;
}
Example #3
0
int Map::Unserialize(LArchive &a)
{
  unsigned temp;
  short stemp;
  int i, n;

  if (!a.Marker(MARK_MAP))
    return -1;

  a.active_map = this; // so the Thinkers can be extracted OK

  // first we load and setup the map, but without spawning any Thinkers if possible
  a << lumpname;
  // TODO load map md5 checksum, make sure the correct map is loaded
  Setup(0, false);
  // remove all the current thinkers (could be done more elegantly by not spawning them
  // in the first place, but... well, at least the Actors are not spawned.)
  Thinker *th, *next;
  for (th = thinkercap.next; th != &thinkercap; th = next)
    {
      next = th->next;
      delete th;
    }
  InitThinkers();

  a << starttic << maptic;
  a << kills << items << secrets;

  line_t *li;
  side_t *si;
  byte    diff, diff2;

  // load changes in geometry
  while (1)
    {
      a << temp;
      if (temp == MARK_END)
	break;
      i = temp; // sector number

      a << diff;
      if (diff & SD_DIFF2)
	a << diff2;
      else
	diff2 = 0;

      char picname[8];

      if (diff & SD_FLOORHT ) a << sectors[i].floorheight;
      if (diff & SD_CEILHT  ) a << sectors[i].ceilingheight;
      if (diff & SD_FLOORPIC)
        {
	  a.Read((byte *)picname, 8);
	  sectors[i].floorpic = materials.Get8char(picname, TEX_floor);
        }
      if (diff & SD_CEILPIC)
        {
	  a.Read((byte *)picname, 8);
	  sectors[i].ceilingpic = materials.Get8char(picname, TEX_floor);
        }
      if (diff & SD_LIGHT)    a << sectors[i].lightlevel;
      if (diff & SD_SPECIAL)  a << sectors[i].special;
      if (diff & SD_TAG)      a << sectors[i].tag;

      if (diff2 & SD_FXOFFS)  a << sectors[i].floor_xoffs;
      if (diff2 & SD_FYOFFS)  a << sectors[i].floor_yoffs;
      if (diff2 & SD_CXOFFS)  a << sectors[i].ceiling_xoffs;
      if (diff2 & SD_CYOFFS)  a << sectors[i].ceiling_yoffs;

      if (diff2 & SD_STAIRLOCK) a << sectors[i].stairlock;
      else sectors[i].stairlock = 0;
      if (diff2 & SD_NEXTSEC)   a << sectors[i].nextsec;
      else sectors[i].nextsec = -1;
      if (diff2 & SD_PREVSEC)   a << sectors[i].prevsec;
      else sectors[i].prevsec = -1;

      if (diff2 & SD_SEQTYPE)   a << sectors[i].seqType;
    }

  while (1)
    {
      a << temp; // line number
      if (temp == MARK_END)
	break;
      li = &lines[temp];

      a << diff;

      if (diff & LD_DIFF2) a << diff2;
      else diff2 = 0;
      if (diff & LD_FLAG)    a << li->flags;
      if (diff & LD_SPECIAL) a << li->special;
      if (diff & LD_ARGS)
	for (i=0; i<5; i++)
	  a << li->args[i];

      si = li->sideptr[0];
      if (diff & LD_S1TEXOFF) a << si->textureoffset;

      if (diff & LD_S1TOPTEX) a << si->toptexture;
      if (diff & LD_S1BOTTEX) a << si->bottomtexture;
      if (diff & LD_S1MIDTEX) a << si->midtexture;

      si = li->sideptr[1];
      if (diff2 & LD_S2TEXOFF) a << si->textureoffset;

      if (diff2 & LD_S2TOPTEX) a << si->toptexture;
      if (diff2 & LD_S2BOTTEX) a << si->bottomtexture;
      if (diff2 & LD_S2MIDTEX) a << si->midtexture;
    }

  //----------------------------------------------
  if (!a.Marker(MARK_POLYOBJ))
    return -2;

  for (i = 0; i < NumPolyobjs; i++)
    {
      a << n;
      if (n != polyobjs[i].id)
	I_Error("Invalid polyobj tag!\n");

      angle_t ang;
      a << ang;
      polyobjs[i].Rotate(ang);
      fixed_t x, y;
      a << x << y;
      polyobjs[i].Move(x - polyobjs[i].origin.x, y - polyobjs[i].origin.y);
    }

  //----------------------------------------------
  // scripts
  if (!a.Marker(MARK_SCRIPT))
    return -3;

  for (acs_script_iter_t i = ACS_scripts.begin(); i != ACS_scripts.end(); i++)
    {
      acs_script_t &s = i->second;
      a << (int &)s.state;
      //a << n; ACSInfo[i].state = acs_state_t(n);
      a << s.wait_data;
    }

  a.Read((byte *)ACS_map_vars, sizeof(ACS_map_vars));

  // FS: restore levelscript
  FS_levelscript->Unserialize(a);

  // restore runningscripts
  // remove all runningscripts first: levelscript may have started them
  FS_ClearRunningScripts(); 

  a << n;
  for (i=0; i<n; i++)
    {
      // create a new runningscript
      runningscript_t *rs = new runningscript_t();
  
      int scriptnum;
      a << scriptnum;
    
      // levelscript?
      if (scriptnum == -1)
	rs->script = FS_levelscript;
      else
	rs->script = FS_levelscript->children[scriptnum];

      a << n; // read out offset from save
      rs->savepoint = rs->script->data + n;
      a << n;
      rs->wait_type = fs_wait_e(n);
      a << rs->wait_data;
      rs->trigger = (Actor *)Thinker::Unserialize(a);
    
      // read out the variables now (fun!)
      // start with basic script slots/labels
  
      for (i=0; i<VARIABLESLOTS; i++)
	rs->variables[i] = rs->script->variables[i];

      // get number of variables
      a << n;
      for (i=0; i<n; i++)
	{
	  svariable_t *sv = (svariable_t*)Z_Malloc(sizeof(svariable_t), PU_LEVEL, 0);
	  sv->Unserialize(a);

	  // link in the new variable
	  int hashkey = script_t::variable_hash(sv->name);
	  sv->next = rs->variables[hashkey];
	  rs->variables[hashkey] = sv;
	}
      
      // hook into chain
      FS_AddRunningScript(rs);
    }

  // TODO Unarchive the script camera

  //----------------------------------------------
  // Thinkers
  if (!a.Marker(MARK_THINK))
    return -4;

  a << n;
  for (i=0; i<n; i++)
    {
      Thinker *th = Thinker::Unserialize(a);
      AddThinker(th);
    }

  if (!a.Marker(MARK_MISC))
    return -5;
  //----------------------------------------------
  // respawnqueue
  a << n;
  for (i=0; i<n; i++)
    {
      a << temp;
      itemrespawnqueue.push_back(&mapthings[temp]);
      a << temp;
      itemrespawntime.push_back(temp);
    }

  //----------------------------------------------
  // the rest
  TID_map.clear();
  a << n;
  for (i=0; i<n; i++)
    {
      Actor *p = NULL;
      a << stemp << temp;
      if (a.GetPtr((int &)temp, (void * &)p))
	TID_map.insert(pair<const short, Actor*>(stemp, p));
      else
	I_Error("Crap in TIDmap!\n");
    }


  return 0;
}