Exemplo n.º 1
0
bool MissionStaticTryAddCharacter(Mission *m, int ch, Vec2i pos)
{
	assert(m->Type == MAPTYPE_STATIC && "invalid map type");
	unsigned short tile = MissionGetTile(m, pos);

	// Remove any characters already there
	MissionStaticTryRemoveCharacterAt(m, pos);

	if (IsClear(tile))
	{
		// Check if the character already has an entry, and add to its list
		// of positions
		bool hasAdded = false;
		CA_FOREACH(CharacterPositions, cp, m->u.Static.Characters)
			if (cp->Index == ch)
			{
				CArrayPushBack(&cp->Positions, &pos);
				hasAdded = true;
				break;
			}
		CA_FOREACH_END()
		// If not, create a new entry
		if (!hasAdded)
		{
			CharacterPositions cp;
			cp.Index = ch;
			CArrayInit(&cp.Positions, sizeof(Vec2i));
			CArrayPushBack(&cp.Positions, &pos);
			CArrayPushBack(&m->u.Static.Characters, &cp);
		}
		return true;
	}
	return false;
}
Exemplo n.º 2
0
EditorResult EditorBrushStartPainting(EditorBrush *b, Mission *m, int isMain)
{
	if (!b->IsPainting)
	{
		b->LastPos = b->Pos;
	}
	b->PaintType = isMain ? b->MainType : b->SecondaryType;
	switch (b->Type)
	{
	case BRUSHTYPE_POINT:
		b->IsPainting = true;
		EditorBrushPaintLine(b, m);
		return EDITOR_RESULT_CHANGED;
	case BRUSHTYPE_LINE:	// fallthrough
	case BRUSHTYPE_BOX:	// fallthrough
	case BRUSHTYPE_BOX_FILLED:	// fallthrough
	case BRUSHTYPE_ROOM:	// fallthrough
	case BRUSHTYPE_SET_EXIT:
		// don't paint until the end
		break;
	case BRUSHTYPE_ROOM_PAINTER:
		EditorBrushPaintRoom(b, m);
		return EDITOR_RESULT_CHANGED;
	case BRUSHTYPE_SELECT:
		// Perform state changes if we've started painting
		if (!b->IsPainting)
		{
			if (!b->IsMoving)
			{
				// check if the click was inside the selection
				// If so, start moving
				if (b->Pos.x >= b->SelectionStart.x &&
					b->Pos.y >= b->SelectionStart.y &&
					b->Pos.x < b->SelectionStart.x + b->SelectionSize.x &&
					b->Pos.y < b->SelectionStart.y + b->SelectionSize.y)
				{
					b->IsMoving = 1;
					b->DragPos = b->Pos;
				}
			}
		}
		break;
	case BRUSHTYPE_FILL:
		// Use flood fill to change all the tiles of the same type to
		// another type
		// Don't paint if target already same type
		// Special case: don't flood-fill doors
		if ((MissionGetTile(m, b->Pos) & MAP_MASKACCESS) != b->PaintType &&
			b->PaintType != MAP_DOOR)
		{
			FloodFillData data;
			data.Fill = MissionFillTile;
			data.IsSame = MissionIsTileSame;
			PaintFloodFillData pData;
			pData.m = m;
			pData.fromType = MissionGetTile(m, b->Pos) & MAP_MASKACCESS;
			pData.toType = b->PaintType;
			data.data = &pData;
			if (CFloodFill(b->Pos, &data))
			{
				return EDITOR_RESULT_CHANGED;
			}
		}
		return EDITOR_RESULT_NONE;
	case BRUSHTYPE_SET_PLAYER_START:
		if (MissionGetTile(m, b->Pos) == MAP_ROOM ||
			MissionGetTile(m, b->Pos) == MAP_FLOOR)
		{
			m->u.Static.Start = b->Pos;
			return EDITOR_RESULT_CHANGED;
		}
		break;
	case BRUSHTYPE_ADD_ITEM:
		if (isMain)
		{
			if (MissionStaticTryAddItem(m, b->u.MapObject, b->Pos))
			{
				return EDITOR_RESULT_CHANGED_AND_RELOAD;
			}
		}
		else
		{
			if (MissionStaticTryRemoveItemAt(m, b->Pos))
			{
				return EDITOR_RESULT_CHANGED_AND_RELOAD;
			}
		}
		break;
	case BRUSHTYPE_ADD_WRECK:
		if (isMain)
		{
			const char **destructibleName =
				CArrayGet(&gMapObjects.Destructibles, b->u.ItemIndex);
			if (MissionStaticTryAddWreck(
				m, StrMapObject(*destructibleName), b->Pos))
			{
				return EDITOR_RESULT_CHANGED_AND_RELOAD;
			}
		}
		else
		{
			if (MissionStaticTryRemoveWreckAt(m, b->Pos))
			{
				return EDITOR_RESULT_CHANGED_AND_RELOAD;
			}
		}
		break;
	case BRUSHTYPE_ADD_CHARACTER:
		if (isMain)
		{
			if (MissionStaticTryAddCharacter(m, b->u.ItemIndex, b->Pos))
			{
				return EDITOR_RESULT_CHANGED_AND_RELOAD;
			}
		}
		else
		{
			if (MissionStaticTryRemoveCharacterAt(m, b->Pos))
			{
				return EDITOR_RESULT_CHANGED_AND_RELOAD;
			}
		}
		break;
	case BRUSHTYPE_ADD_OBJECTIVE:
		if (isMain)
		{
			if (MissionStaticTryAddObjective(
				m, b->u.ItemIndex, b->Index2, b->Pos))
			{
				return EDITOR_RESULT_CHANGED_AND_RELOAD;
			}
		}
		else
		{
			if (MissionStaticTryRemoveObjectiveAt(m, b->Pos))
			{
				return EDITOR_RESULT_CHANGED_AND_RELOAD;
			}
		}
		break;
	case BRUSHTYPE_ADD_KEY:
		if (isMain)
		{
			if (MissionStaticTryAddKey(m, b->u.ItemIndex, b->Pos))
			{
				return EDITOR_RESULT_CHANGED_AND_RELOAD;
			}
		}
		else
		{
			if (MissionStaticTryRemoveKeyAt(m, b->Pos))
			{
				return EDITOR_RESULT_CHANGED_AND_RELOAD;
			}
		}
		break;
	case BRUSHTYPE_SET_KEY:
		if (isMain || b->u.ItemIndex > 0)
		{
			if (MissionStaticTrySetKey(m, b->u.ItemIndex, b->Pos))
			{
				return EDITOR_RESULT_CHANGED_AND_RELOAD;
			}
		}
		else
		{
			if (MissionStaticTryUnsetKeyAt(m, b->Pos))
			{
				return EDITOR_RESULT_CHANGED_AND_RELOAD;
			}
		}
		break;
	default:
		assert(0 && "unknown brush type");
		break;
	}
	b->IsPainting = 1;
	return EDITOR_RESULT_NONE;
}