예제 #1
0
파일: C4Effect.cpp 프로젝트: 772/openclonk
void C4Effect::CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers)
{
	// read name
	pComp->Separator(StdCompiler::SEP_START); // '('
	// read priority
	pComp->Value(iPriority); pComp->Separator();
	// read time and intervall
	pComp->Value(iTime); pComp->Separator();
	pComp->Value(iInterval); pComp->Separator();
	// read object number
	pComp->Value(CommandTarget); pComp->Separator();
	// read ID
	pComp->Value(idCommandTarget); pComp->Separator();
	// proplist
	C4PropListNumbered::CompileFunc(pComp, numbers);
	pComp->Separator(StdCompiler::SEP_END); // ')'
	// is there a next effect?
	bool fNext = !! pNext;
	if (pComp->hasNaming())
	{
		if (fNext || pComp->isCompiler())
			fNext = pComp->Separator();
	}
	else
		pComp->Value(fNext);
	if (!fNext) return;
	// read next
	pComp->Value(mkParAdapt(mkPtrAdaptNoNull(pNext), numbers));
	// denumeration and callback assignment will be done later
}
예제 #2
0
void C4TeamList::CompileFunc(StdCompiler *pComp)
{
	// if (pComp->isCompiler()) Clear(); - do not clear, because this would corrupt  the fCustom-flag
	pComp->Value(mkNamingAdapt(fActive,               "Active",               true));
	pComp->Value(mkNamingAdapt(fCustom,               "Custom",               true));
	pComp->Value(mkNamingAdapt(fAllowHostilityChange, "AllowHostilityChange", false));
	pComp->Value(mkNamingAdapt(fAllowTeamSwitch,      "AllowTeamSwitch",      false));
	pComp->Value(mkNamingAdapt(fAutoGenerateTeams,    "AutoGenerateTeams",    false));
	pComp->Value(mkNamingAdapt(iLastTeamID, "LastTeamID", 0));

	StdEnumEntry<TeamDist> TeamDistEntries[] =
	{
		{ "Free", TEAMDIST_Free },
		{ "Host", TEAMDIST_Host },
		{ "None", TEAMDIST_None },
		{ "Random", TEAMDIST_Random },
		{ "RandomInv", TEAMDIST_RandomInv },
	};
	pComp->Value(mkNamingAdapt(mkEnumAdaptT<uint8_t>(eTeamDist, TeamDistEntries), "TeamDistribution", TEAMDIST_Free));

	pComp->Value(mkNamingAdapt(fTeamColors, "TeamColors", false));
	pComp->Value(mkNamingAdapt(iMaxScriptPlayers, "MaxScriptPlayers", 0));
	pComp->Value(mkNamingAdapt(mkParAdapt(sScriptPlayerNames, StdCompiler::RCT_All), "ScriptPlayerNames", StdStrBuf()));

	int32_t iOldTeamCount = iTeamCount;
	pComp->Value(mkNamingCountAdapt(iTeamCount,  "Team"));

	if (pComp->isCompiler())
	{
		while (iOldTeamCount--) delete ppList[iOldTeamCount];
		delete [] ppList;
		if ((iTeamCapacity = iTeamCount))
		{
			ppList = new C4Team *[iTeamCapacity];
			memset(ppList, 0, sizeof(C4Team *)*iTeamCapacity);
		}
		else
			ppList = NULL;
	}

	if (iTeamCount)
	{
		// Force compiler to spezialize
		mkPtrAdaptNoNull(*ppList);
		// Save team list, using map-function.
		pComp->Value(mkNamingAdapt(
		               mkArrayAdaptMap(ppList, iTeamCount, mkPtrAdaptNoNull<C4Team>),
		               "Team"));
	}

	if (pComp->isCompiler())
	{
		// adjust last team ID, which may not be set properly for player-generated team files
		iLastTeamID = std::max(GetLargestTeamID(), iLastTeamID);
		// force automatic generation of teams if none are defined
		if (!iTeamCount) fAutoGenerateTeams = true;
	}
}
예제 #3
0
void C4Effect::CompileFunc(StdCompiler *pComp, C4PropList * Owner, C4ValueNumbers * numbers)
{
	if (pComp->isCompiler()) Target = Owner;
	// read name
	pComp->Separator(StdCompiler::SEP_START); // '('
	// read priority
	pComp->Value(iPriority); pComp->Separator();
	// read time and intervall
	pComp->Value(iTime); pComp->Separator();
	pComp->Value(iInterval); pComp->Separator();
	// read object number
	// FIXME: replace with this when savegame compat breaks for other reasons
	// pComp->Value(mkParAdapt(CommandTarget, numbers));
	int32_t nptr = 0;
	if (!pComp->isCompiler() && CommandTarget.getPropList() && CommandTarget._getPropList()->GetPropListNumbered())
		nptr = CommandTarget._getPropList()->GetPropListNumbered()->Number;
	pComp->Value(nptr);
	if (pComp->isCompiler())
		CommandTarget.SetObjectEnum(nptr);
	pComp->Separator();
	// read ID
	if (pComp->isDecompiler())
	{
		const C4PropListStatic * p = CommandTarget.getPropList() ? CommandTarget._getPropList()->IsStatic() : NULL;
		if (p)
			p->RefCompileFunc(pComp, numbers);
		else
			pComp->String(const_cast<char*>("None"), 5, StdCompiler::RCT_ID);
	}
	else
	{
		StdStrBuf s;
		pComp->Value(mkParAdapt(s, StdCompiler::RCT_ID));
		// An Object trumps a definition as command target
		if (!nptr)
			if (!::ScriptEngine.GetGlobalConstant(s.getData(), &CommandTarget))
				CommandTarget.Set0();
	}
	pComp->Separator();
	// proplist
	C4PropListNumbered::CompileFunc(pComp, numbers);
	pComp->Separator(StdCompiler::SEP_END); // ')'
	// is there a next effect?
	bool fNext = !! pNext;
	if (pComp->hasNaming())
	{
		if (fNext || pComp->isCompiler())
			fNext = pComp->Separator();
	}
	else
		pComp->Value(fNext);
	if (!fNext) return;
	// read next
	pComp->Value(mkParAdapt(mkPtrAdaptNoNull(pNext), Owner, numbers));
	// denumeration and callback assignment will be done later
}
예제 #4
0
void C4RecordChunk::CompileFunc(StdCompiler *pComp) {
  pComp->Value(mkNamingAdapt(Frame, "Frame"));
  pComp->Value(mkNamingAdapt(mkIntAdapt(Type), "Type"));
  switch (Type) {
    case RCT_Ctrl:
      pComp->Value(mkPtrAdaptNoNull(pCtrl));
      break;
    case RCT_CtrlPkt:
      pComp->Value(mkPtrAdaptNoNull(pPkt));
      break;
    case RCT_End:
      break;
    case RCT_Frame:
      break;
    case RCT_File:
      pComp->Value(Filename);
      pComp->Value(mkPtrAdaptNoNull(pFileData));
      break;
    default:
      pComp->Value(mkPtrAdaptNoNull(pDbg));
      break;
  }
}
예제 #5
0
void C4ObjectList::CompileFunc(StdCompiler *pComp, bool fSkipPlayerObjects, C4ValueNumbers * numbers)
{
	// "Object" section count
	int32_t iObjCnt = ObjectCount();
	pComp->Value(mkNamingCountAdapt(iObjCnt, "Object"));
	if (pComp->isDecompiler())
	{
		// skipping player objects would screw object counting in non-naming compilers
		assert(!fSkipPlayerObjects || pComp->hasNaming());
		// Decompile all objects in reverse order
		for (C4ObjectLink *pPos = Last; pPos; pPos = pPos->Prev)
			if (pPos->Obj->Status)
				if (!fSkipPlayerObjects || !pPos->Obj->IsUserPlayerObject())
					pComp->Value(mkNamingAdapt(mkParAdapt(*pPos->Obj, numbers), "Object"));
	}
	else
	{
		// FIXME: Check that no PlayerObjects are loaded when fSkipPlayerObjects is true
		// i.e. that loading and saving was done with the same flag.
		// Remove previous data
		Clear();
		// Load objects, add them to the list.
		for (int i = 0; i < iObjCnt; i++)
		{
			C4Object *pObj = NULL;
			try
			{
				pComp->Value(mkNamingAdapt(mkParAdapt(mkPtrAdaptNoNull(pObj), numbers), "Object"));
				Add(pObj, stReverse);
			}
			catch (StdCompiler::Exception *pExc)
			{
				// Failsafe object loading: If an error occurs during object loading, just skip that object and load the next one
				if (!pExc->Pos.getLength())
					LogF("ERROR: Object loading: %s", pExc->Msg.getData());
				else
					LogF("ERROR: Object loading(%s): %s", pExc->Pos.getData(), pExc->Msg.getData());
				delete pExc;
			}
		}
	}
}
예제 #6
0
BOOL C4Playback::ReadBinary(const StdBuf &Buf) {
  // sequential reading: Take over rest from last buffer
  const StdBuf *pUseBuf;
  uint32_t iFrame = 0;
  if (fLoadSequential) {
    sequentialBuffer.Append(Buf);
    pUseBuf = &sequentialBuffer;
    iFrame = iLastSequentialFrame;
  } else
    pUseBuf = &Buf;
  // get buffer data
  size_t iPos = 0;
  bool fFinished = false;
  do {
    // unpack header
    if (pUseBuf->getSize() - iPos < sizeof(C4RecordChunkHead)) break;
    const C4RecordChunkHead *pHead =
        getBufPtr<C4RecordChunkHead>(*pUseBuf, iPos);
    // get chunk
    iPos += sizeof(C4RecordChunkHead);
    StdBuf Chunk = pUseBuf->getPart(iPos, pUseBuf->getSize() - iPos);
    // Create entry
    C4RecordChunk c;
    c.Frame = (iFrame += pHead->iFrm);
    c.Type = pHead->Type;
    // Unpack data
    try {
      // Initialize compiler
      StdCompilerBinRead Compiler;
      Compiler.setInput(Chunk.getRef());
      Compiler.Begin();
      // Read chunk
      switch (pHead->Type) {
        case RCT_Ctrl:
          Compiler.Value(mkPtrAdaptNoNull(c.pCtrl));
          break;
        case RCT_CtrlPkt:
          Compiler.Value(mkPtrAdaptNoNull(c.pPkt));
          break;
        case RCT_End:
          fFinished = true;
          break;
        case RCT_File:
          Compiler.Value(c.Filename);
          Compiler.Value(mkPtrAdaptNoNull(c.pFileData));
          break;
        default:
          // debugrec
          if (pHead->Type >= 0x80) Compiler.Value(mkPtrAdaptNoNull(c.pDbg));
      }
      // Advance over data
      Compiler.End();
      iPos += Compiler.getPosition();
    } catch (StdCompiler::EOFException *pEx) {
      // This is to be expected for sequential reading
      if (fLoadSequential) {
        iPos -= sizeof(C4RecordChunkHead);
        iFrame -= pHead->iFrm;
        delete pEx;
        break;
      }
      LogF("Record: Binary unpack error: %s", pEx->Msg.getData());
      c.Delete();
      delete pEx;
      return FALSE;
    } catch (StdCompiler::Exception *pEx) {
      LogF("Record: Binary unpack error: %s", pEx->Msg.getData());
      c.Delete();
      delete pEx;
      return FALSE;
    }
    // Add to list
    chunks.push_back(c);
    c.pPkt = NULL;
  } while (!fFinished);
  // erase everything but the trailing part from sequential buffer
  if (fLoadSequential) {
    if (iPos >= sequentialBuffer.getSize())
      sequentialBuffer.Clear();
    else if (iPos) {
      sequentialBuffer.Move(iPos, sequentialBuffer.getSize() - iPos);
      sequentialBuffer.Shrink(iPos);
    }
    iLastSequentialFrame = iFrame;
  }
  return TRUE;
}