func (suite *DynamicObjPropStoreSuite) TestSwapReplacesWrapped(c *check.C) {
	objId0 := res.MakeObjectID(res.ObjectClass(0), res.ObjectSubclass(0), res.ObjectType(0))
	objId1 := res.MakeObjectID(res.ObjectClass(0), res.ObjectSubclass(0), res.ObjectType(1))
	secondData := suite.testData(6)
	provider0 := suite.createProvider(func(consumer objprop.Consumer) {
		consumer.Consume(objId0, suite.testData(3))
		consumer.Consume(objId1, suite.testData(3))
	})
	provider1 := suite.createProvider(func(consumer objprop.Consumer) {
		consumer.Consume(objId0, suite.testData(5))
		consumer.Consume(objId1, secondData)
	})

	testStore := NewDynamicObjPropStore(store.NewProviderBacked(provider0, func() {}))
	testStore.Swap(func(oldStore objprop.Store) objprop.Store {
		return store.NewProviderBacked(provider1, func() {})
	})

	retrievedData := testStore.Get(objId1)

	c.Check(retrievedData.Common, check.DeepEquals, secondData.Common)
	c.Check(retrievedData.Generic, check.DeepEquals, secondData.Generic)
	c.Check(retrievedData.Specific, check.DeepEquals, secondData.Specific)
}
func (suite *DynamicObjPropStoreSuite) TestGetReturnsBlockFromWrapped(c *check.C) {
	objId := res.MakeObjectID(res.ObjectClass(0), res.ObjectSubclass(0), res.ObjectType(0))
	initData := suite.testData(4)
	provider := suite.createProvider(func(consumer objprop.Consumer) {
		consumer.Consume(objId, initData)
	})

	wrappedStore := store.NewProviderBacked(provider, func() {})
	testStore := NewDynamicObjPropStore(wrappedStore)

	retrievedData := testStore.Get(objId)

	c.Check(retrievedData.Common, check.DeepEquals, initData.Common)
	c.Check(retrievedData.Generic, check.DeepEquals, initData.Generic)
	c.Check(retrievedData.Specific, check.DeepEquals, initData.Specific)
}
func (suite *DynamicObjPropStoreSuite) TestPutInsertsToWrapped(c *check.C) {
	objId := res.MakeObjectID(res.ObjectClass(0), res.ObjectSubclass(0), res.ObjectType(0))
	provider := suite.createProvider(func(consumer objprop.Consumer) {
		consumer.Consume(objId, suite.testData(0))
	})

	wrappedStore := store.NewProviderBacked(provider, func() {})
	testStore := NewDynamicObjPropStore(wrappedStore)
	newData := suite.testData(1)

	testStore.Put(objId, newData)

	wrappedData := wrappedStore.Get(objId)

	c.Check(wrappedData.Common, check.DeepEquals, newData.Common)
	c.Check(wrappedData.Generic, check.DeepEquals, newData.Generic)
	c.Check(wrappedData.Specific, check.DeepEquals, newData.Specific)
}
Beispiel #4
0
// AddObject adds a new object at given tile.
func (level *Level) AddObject(template *model.LevelObjectTemplate) (createdIndex int, err error) {
	level.mutex.Lock()
	defer level.mutex.Unlock()

	objID := res.MakeObjectID(res.ObjectClass(template.Class),
		res.ObjectSubclass(template.Subclass), res.ObjectType(template.Type))

	classMeta := data.LevelObjectClassMetaEntry(objID.Class)
	classStore := level.store.Get(res.ResourceID(4000 + level.id*100 + 10 + int(objID.Class)))
	classTable := logic.DecodeLevelObjectClassTable(classStore.BlockData(0), classMeta.EntrySize)
	classChain := classTable.AsChain()
	classIndex, classErr := classChain.AcquireLink()

	if classErr != nil {
		err = classErr
		return
	}
	classEntry := classTable.Entry(classIndex)
	classEntryData := classEntry.Data()
	for index := 0; index < len(classEntryData); index++ {
		classEntryData[index] = 0x00
	}

	objectIndex, objectErr := level.objectChain.AcquireLink()
	if objectErr != nil {
		classChain.ReleaseLink(classIndex)
		err = objectErr
		return
	}
	createdIndex = int(objectIndex)

	locations := []logic.TileLocation{logic.AtTile(uint16(template.TileX), uint16(template.TileY))}

	crossrefIndex, crossrefErr := level.crossrefList.AddObjectToMap(uint16(objectIndex), level.tileMap, locations)
	if crossrefErr != nil {
		classChain.ReleaseLink(classIndex)
		level.objectChain.ReleaseLink(objectIndex)
		err = crossrefErr
		return
	}
	crossrefEntry := level.crossrefList.Entry(crossrefIndex)

	objectEntry := &level.objectList[objectIndex]
	objectEntry.InUse = 1
	objectEntry.Class = objID.Class
	objectEntry.Subclass = objID.Subclass
	objectEntry.Type = objID.Type
	objectEntry.X = data.MapCoordinateOf(byte(template.TileX), byte(template.FineX))
	objectEntry.Y = data.MapCoordinateOf(byte(template.TileY), byte(template.FineY))
	objectEntry.Z = byte(template.Z)
	objectEntry.Rot1 = 0
	objectEntry.Rot2 = 0
	objectEntry.Rot3 = 0
	objectEntry.Hitpoints = 1

	objectEntry.CrossReferenceTableIndex = uint16(crossrefIndex)
	crossrefEntry.LevelObjectTableIndex = uint16(objectIndex)

	objectEntry.ClassTableIndex = uint16(classIndex)
	classEntry.LevelObjectTableIndex = uint16(objectIndex)

	classStore.SetBlockData(0, classTable.Encode())

	objWriter := bytes.NewBuffer(nil)
	binary.Write(objWriter, binary.LittleEndian, level.objectList)
	level.objectListStore.SetBlockData(0, objWriter.Bytes())

	level.crossrefListStore.SetBlockData(0, level.crossrefList.Encode())
	level.onTileDataChanged()

	return
}
// GET /projects/{project-id}/objects/{class}/{subclass}/{type}/icon/raw
func (resource *WorkspaceResource) getObjectIconAsRaw(request *restful.Request, response *restful.Response) {
	projectID := request.PathParameter("project-id")
	project, err := resource.ws.Project(projectID)

	if err == nil {
		classID, _ := strconv.ParseInt(request.PathParameter("class"), 10, 8)
		subclassID, _ := strconv.ParseInt(request.PathParameter("subclass"), 10, 8)
		typeID, _ := strconv.ParseInt(request.PathParameter("type"), 10, 8)
		objID := res.MakeObjectID(res.ObjectClass(classID), res.ObjectSubclass(subclassID), res.ObjectType(typeID))
		bmp := project.GameObjects().Icon(objID)
		var entity model.RawBitmap

		entity.Width = int(bmp.ImageWidth())
		entity.Height = int(bmp.ImageHeight())
		var pixel []byte

		for row := 0; row < entity.Height; row++ {
			pixel = append(pixel, bmp.Row(row)...)
		}
		entity.Pixels = base64.StdEncoding.EncodeToString(pixel)

		response.WriteEntity(entity)
	} else {
		response.AddHeader("Content-Type", "text/plain")
		response.WriteErrorString(http.StatusBadRequest, err.Error())
		return
	}
}
// GET /projects/{project-id}/objects/{class}/{subclass}/{type}
func (resource *WorkspaceResource) getGameObject(request *restful.Request, response *restful.Response) {
	projectID := request.PathParameter("project-id")
	project, err := resource.ws.Project(projectID)

	if err == nil {
		classID, _ := strconv.ParseInt(request.PathParameter("class"), 10, 8)
		subclassID, _ := strconv.ParseInt(request.PathParameter("subclass"), 10, 8)
		typeID, _ := strconv.ParseInt(request.PathParameter("type"), 10, 8)
		objID := res.MakeObjectID(res.ObjectClass(classID), res.ObjectSubclass(subclassID), res.ObjectType(typeID))
		entity := resource.objectEntity(project, objID)

		response.WriteEntity(entity)
	} else {
		response.AddHeader("Content-Type", "text/plain")
		response.WriteErrorString(http.StatusBadRequest, err.Error())
		return
	}
}
func (library *ReleaseStoreLibrary) serializeObjpropStore(store objprop.Store) []byte {
	buffer := serial.NewByteStore()
	consumer := dosObjprop.NewConsumer(buffer, library.descriptors)

	for classIndex, classDesc := range library.descriptors {
		for subclassIndex, subclassDesc := range classDesc.Subclasses {
			for typeIndex := uint32(0); typeIndex < subclassDesc.TypeCount; typeIndex++ {
				objID := res.MakeObjectID(res.ObjectClass(classIndex), res.ObjectSubclass(subclassIndex), res.ObjectType(typeIndex))
				data := store.Get(objID)
				consumer.Consume(objID, data)
			}
		}
	}
	consumer.Finish()

	return buffer.Data()
}
// NewGameObjects returns a new instance of GameObjects.
func NewGameObjects(library io.StoreLibrary) (gameObjects *GameObjects, err error) {
	var cybstrng [model.LanguageCount]chunk.Store
	var objart chunk.Store
	var objProperties objprop.Store

	if err == nil {
		objart, err = library.ChunkStore("objart.res")
	}
	if err == nil {
		objProperties, err = library.ObjpropStore("objprop.dat")
	}
	for i := 0; i < model.LanguageCount && err == nil; i++ {
		cybstrng[i], err = library.ChunkStore(localized[i].cybstrng)
	}
	if err == nil {
		gameObjects = &GameObjects{
			cybstrng:       cybstrng,
			cp:             text.DefaultCodepage(),
			desc:           objprop.StandardProperties(),
			objProperties:  objProperties,
			objart:         objart,
			objIconOffsets: make(map[res.ObjectID]int),
			mapIconOffsets: make(map[res.ObjectID]int)}

		offset := 1
		for classIndex, classDesc := range gameObjects.desc {
			for subclassIndex, subclassDesc := range classDesc.Subclasses {
				for typeIndex := uint32(0); typeIndex < subclassDesc.TypeCount; typeIndex++ {
					objID := res.MakeObjectID(res.ObjectClass(classIndex), res.ObjectSubclass(subclassIndex), res.ObjectType(typeIndex))
					commonProperties := gameObjects.commonProperties(objID)
					extraImages := int(commonProperties.Extra >> 4)

					gameObjects.objIconOffsets[objID] = offset
					offset = offset + 3 + extraImages
					gameObjects.mapIconOffsets[objID] = offset - 1
				}
			}
		}
	}

	return
}