예제 #1
0
static const char *MissionGetObjectiveFlags(UIObject *o, void *vData)
{
	int flags;
	static char s[128];
	UNUSED(o);
	MissionIndexData *data = vData;
	if (!CampaignGetCurrentMission(data->co)) return NULL;
	if ((int)CampaignGetCurrentMission(data->co)->Objectives.size <=
		data->index)
	{
		return NULL;
	}
	flags = GetMissionObjective(
		CampaignGetCurrentMission(data->co), data->index)->Flags;
	if (!flags)
	{
		return "(normal)";
	}
	sprintf(s, "%s %s %s %s %s",
		(flags & OBJECTIVE_HIDDEN) ? "hidden" : "",
		(flags & OBJECTIVE_POSKNOWN) ? "pos.known" : "",
		(flags & OBJECTIVE_HIACCESS) ? "access" : "",
		(flags & OBJECTIVE_UNKNOWNCOUNT) ? "no-count" : "",
		(flags & OBJECTIVE_NOACCESS) ? "no-access" : "");
	return s;
}
예제 #2
0
static void MissionChangeRoomsOverlap(void *data, int d)
{
	UNUSED(d);
	CampaignOptions *co = data;
	CampaignGetCurrentMission(co)->u.Cave.Rooms.Overlap =
		!CampaignGetCurrentMission(co)->u.Cave.Rooms.Overlap;
}
예제 #3
0
static void MissionChangeRoomMax(void *data, int d)
{
	CampaignOptions *co = data;
	CampaignGetCurrentMission(co)->u.Cave.Rooms.Max =
		CLAMP(CampaignGetCurrentMission(co)->u.Cave.Rooms.Max + d, 5, 50);
	CampaignGetCurrentMission(co)->u.Cave.Rooms.Min = MIN(
		CampaignGetCurrentMission(co)->u.Cave.Rooms.Min,
		CampaignGetCurrentMission(co)->u.Cave.Rooms.Max);
}
예제 #4
0
static const char *MissionGetRoomWallPadStr(UIObject *o, void *data)
{
	static char s[128];
	UNUSED(o);
	CampaignOptions *co = data;
	if (!CampaignGetCurrentMission(co)) return NULL;
	sprintf(s, "RoomWallPad: %d", CampaignGetCurrentMission(co)->u.Cave.Rooms.WallPad);
	return s;
}
예제 #5
0
static const char *MissionGetSquareCountStr(UIObject *o, void *data)
{
	static char s[128];
	UNUSED(o);
	CampaignOptions *co = data;
	if (!CampaignGetCurrentMission(co)) return NULL;
	sprintf(s, "Sqr: %d", CampaignGetCurrentMission(co)->u.Cave.Squares);
	return s;
}
예제 #6
0
static const char *MissionGetObjectiveStr(UIObject *o, void *vData)
{
	UNUSED(o);
	MissionIndexData *data = vData;
	if (!CampaignGetCurrentMission(data->co)) return NULL;
	if ((int)CampaignGetCurrentMission(data->co)->Objectives.size <= data->index) return NULL;
	return ObjectiveTypeStr(((const Objective *)CArrayGet(
		&CampaignGetCurrentMission(data->co)->Objectives, data->index))->Type);
}
예제 #7
0
static void MissionDrawDoorEnabled(
	UIObject *o, GraphicsDevice *g, struct vec2i pos, void *data)
{
	UNUSED(o);
	UNUSED(g);
	CampaignOptions *co = data;
	if (!CampaignGetCurrentMission(co)) return;
	DisplayFlag(
		svec2i_add(pos, o->Pos), "Doors",
		CampaignGetCurrentMission(co)->u.Cave.DoorsEnabled,
		UIObjectIsHighlighted(o));
}
예제 #8
0
static void MissionDrawRoomsOverlap(
	UIObject *o, GraphicsDevice *g, struct vec2i pos, void *data)
{
	UNUSED(o);
	UNUSED(g);
	UNUSED(pos);
	CampaignOptions *co = data;
	if (!CampaignGetCurrentMission(co)) return;
	DisplayFlag(
		svec2i_add(pos, o->Pos), "Room overlap",
		CampaignGetCurrentMission(co)->u.Cave.Rooms.Overlap,
		UIObjectIsHighlighted(o));
}
예제 #9
0
static const char *MissionGetObjectiveTotal(UIObject *o, void *vData)
{
	static char s[128];
	UNUSED(o);
	MissionIndexData *data = vData;
	if (!CampaignGetCurrentMission(data->co)) return NULL;
	if ((int)CampaignGetCurrentMission(data->co)->Objectives.size <=
		data->index)
	{
		return NULL;
	}
	sprintf(s, "out of %d", GetMissionObjective(
		CampaignGetCurrentMission(data->co), data->index)->Count);
	return s;
}
예제 #10
0
static void Delete(int xc, int yc)
{
	Mission *mission = CampaignGetCurrentMission(&gCampaign);
	switch (yc)
	{
	case YC_CHARACTERS:
		DeleteCharacter(mission, xc);
		break;

	case YC_SPECIALS:
		DeleteSpecial(mission, xc);
		break;

	case YC_ITEMS:
		DeleteItem(mission, xc);
		break;

	default:
		if (yc >= YC_OBJECTIVES)
		{
			DeleteObjective(mission, yc - YC_OBJECTIVES);
		}
		else
		{
			DeleteMission(&gCampaign);
		}
		AdjustYC(&yc);
		break;
	}
	fileChanged = 1;
	Setup(0);
}
예제 #11
0
static void MissionChangeDoorEnabled(void *data, int d)
{
	UNUSED(d);
	CampaignOptions *co = data;
	Mission *m = CampaignGetCurrentMission(co);
	m->u.Cave.DoorsEnabled = !m->u.Cave.DoorsEnabled;
}
예제 #12
0
static void MissionChangeObjectiveRequired(void *vData, int d)
{
	MissionIndexData *data = vData;
	Objective *o = GetMissionObjective(
		CampaignGetCurrentMission(data->co), data->index);
	o->Required = CLAMP_OPPOSITE(o->Required + d, 0, MIN(100, o->Count));
}
예제 #13
0
void CampaignAndMissionSetup(
	int buildTables, CampaignOptions *campaign, struct MissionOptions *mo)
{
	CampaignSeedRandom(campaign);
	SetupMission(
		buildTables,
		CampaignGetCurrentMission(campaign), mo,
		campaign->MissionIndex);
}
예제 #14
0
static const char *CampaignGetSeedStr(UIObject *o, void *data)
{
	static char s[128];
	UNUSED(o);
	CampaignOptions *co = data;
	if (!CampaignGetCurrentMission(co)) return NULL;
	sprintf(s, "Seed: %d", ConfigGetInt(&gConfig, "Game.RandomSeed"));
	return s;
}
예제 #15
0
static const char *MissionGetFillPercentStr(UIObject *o, void *data)
{
	UNUSED(o);
	CampaignOptions *co = data;
	const Mission *m = CampaignGetCurrentMission(co);
	if (m == NULL) return NULL;
	static char s[128];
	sprintf(s, "Fill: %d%%", m->u.Cave.FillPercent);
	return s;
}
예제 #16
0
static const char *MissionGetCorridorWidthStr(UIObject *o, void *data)
{
	UNUSED(o);
	CampaignOptions *co = data;
	const Mission *m = CampaignGetCurrentMission(co);
	if (m == NULL) return NULL;
	static char s[128];
	sprintf(s, "CorridorWidth: %d", m->u.Cave.CorridorWidth);
	return s;
}
예제 #17
0
static void MissionChangeFillPercent(void *data, int d)
{
	CampaignOptions *co = data;
	Mission *m = CampaignGetCurrentMission(co);
	if (gEventHandlers.keyboard.modState & KMOD_SHIFT)
	{
		d *= 10;
	}
	m->u.Cave.FillPercent = CLAMP(m->u.Cave.FillPercent + d, 0, 100);
}
예제 #18
0
void DeleteMission(CampaignOptions *co)
{
	CASSERT(
		co->MissionIndex < (int)co->Setting.Missions.size,
		"invalid mission index");
	MissionTerminate(CampaignGetCurrentMission(co));
	CArrayDelete(&co->Setting.Missions, co->MissionIndex);
	if (co->MissionIndex >= (int)co->Setting.Missions.size)
	{
		co->MissionIndex = MAX(0, (int)co->Setting.Missions.size - 1);
	}
}
예제 #19
0
static void MissionCheckTypeStatic(UIObject *o, void *data)
{
	CampaignOptions *co = data;
	Mission *m = CampaignGetCurrentMission(co);
	if (!m || m->Type != MAPTYPE_STATIC)
	{
		o->IsVisible = false;
		// Need to unhighlight to prevent children being drawn
		UIObjectUnhighlight(o);
		return;
	}
	o->IsVisible = true;
}
예제 #20
0
static void ObjectiveChangeType(void *vData, int d)
{
	UNUSED(d);
	ObjectiveChangeTypeData *data = vData;
	Objective *o = GetMissionObjective(
		CampaignGetCurrentMission(data->C), data->ObjectiveIdx);
	if (o->Type == data->Type)
	{
		return;
	}
	o->Type = data->Type;
	MissionResetObjectiveIndex(o);
}
예제 #21
0
static Vec2i GetMouseTile(EventHandlers *e)
{
	Mission *m = CampaignGetCurrentMission(&gCampaign);
	if (!m)
	{
		return Vec2iNew(-1, -1);
	}
	else
	{
		return Vec2iNew(
			(e->mouse.currentPos.x - sDrawBuffer.dx) / TILE_WIDTH + sDrawBuffer.xStart,
			(e->mouse.currentPos.y - sDrawBuffer.dy) / TILE_HEIGHT + sDrawBuffer.yStart);
	}
}
예제 #22
0
static void AdjustXC(int yc, int *xc)
{
	Mission *mission = CampaignGetCurrentMission(&gCampaign);
	switch (yc)
	{
	case YC_CAMPAIGNTITLE:
		*xc = CLAMP_OPPOSITE(*xc, 0, XC_CAMPAIGNDESC);
		break;

	case YC_MISSIONTITLE:
		*xc = CLAMP_OPPOSITE(*xc, 0, XC_MUSICFILE);
		break;

	case YC_MISSIONLOOKS:
		*xc = CLAMP_OPPOSITE(*xc, 0, XC_COLOR4);
		break;

	case YC_CHARACTERS:
		if (mission && mission->Enemies.size > 0)
		{
			*xc = CLAMP_OPPOSITE(*xc, 0, (int)mission->Enemies.size - 1);
		}
		break;

	case YC_SPECIALS:
		if (mission && mission->SpecialChars.size > 0)
		{
			*xc = CLAMP_OPPOSITE(*xc, 0, (int)mission->SpecialChars.size - 1);
		}
		break;

	case YC_ITEMS:
		if (mission && mission->Items.size > 0)
		{
			*xc = CLAMP_OPPOSITE(*xc, 0, (int)mission->Items.size - 1);
		}
		break;

	case YC_WEAPONS:
		*xc = CLAMP_OPPOSITE(*xc, 0, XC_MAXWEAPONS);
		break;

	default:
		if (yc >= YC_OBJECTIVES)
		{
			*xc = CLAMP_OPPOSITE(*xc, 0, XC_FLAGS);
		}
		break;
	}
}
예제 #23
0
void DrawKey(UIObject *o, GraphicsDevice *g, struct vec2i pos, void *vData)
{
	const IndexedEditorBrush *data = vData;
	if (data->u.ItemIndex == -1)
	{
		// No key; don't draw
		return;
	}
	const Mission *m = CampaignGetCurrentMission(&gCampaign);
	const Pic *pic = CPicGetPic(
		&KeyPickupClass(m->KeyStyle, data->u.ItemIndex)->Pic, 0);
	pos = svec2i_add(svec2i_add(pos, o->Pos), svec2i_scale_divide(o->Size, 2));
	pos = svec2i_subtract(pos, svec2i_scale_divide(pic->size, 2));
	Blit(g, pic, pos);
}
예제 #24
0
static void MissionChangeObjectiveTotal(void *vData, int d)
{
	MissionIndexData *data = vData;
	const Mission *m = CampaignGetCurrentMission(data->co);
	Objective *o = GetMissionObjective(m, data->index);
	o->Count = CLAMP_OPPOSITE(o->Count + d, o->Required, 100);
	// Don't let the total reduce to less than static ones we've placed
	if (m->Type == MAPTYPE_STATIC)
	{
		CA_FOREACH(const ObjectivePositions, op, m->u.Static.Objectives)
			if (op->Index == data->index)
			{
				o->Count = MAX(o->Count, (int)op->Positions.size);
				break;
			}
		CA_FOREACH_END()
	}
예제 #25
0
static void Setup(int buildTables)
{
	Mission *m = CampaignGetCurrentMission(&gCampaign);
	if (!m)
	{
		return;
	}
	MissionCopy(&lastMission, &currentMission);
	MissionCopy(&currentMission, m);
	MissionOptionsTerminate(&gMission);
	CampaignAndMissionSetup(buildTables, &gCampaign, &gMission);
	MakeBackground(&gGraphicsDevice, buildTables);
	sCursorTile = TileNone();

	Autosave();

	sJustLoaded = true;
	sHasUnbakedChanges = false;
}
static void DrawObjective(
	UIObject *o, GraphicsDevice *g, Vec2i pos, void *vData)
{
	UNUSED(g);
	EditorBrushAndCampaign *data = vData;
	Mission *m = CampaignGetCurrentMission(data->Campaign);
	const Objective *obj = CArrayGet(&m->Objectives, data->Brush.u.ItemIndex);
	CharacterStore *store = &data->Campaign->Setting.characters;
	pos = Vec2iAdd(Vec2iAdd(pos, o->Pos), Vec2iScaleDiv(o->Size, 2));
	switch (obj->Type)
	{
	case OBJECTIVE_KILL:
		{
			Character *c = CArrayGet(
				&store->OtherChars,
				CharacterStoreGetSpecialId(store, data->Brush.Index2));
			DrawCharacterSimple(c, pos, DIRECTION_DOWN, false, false);
		}
		break;
	case OBJECTIVE_RESCUE:
		{
			Character *c = CArrayGet(
				&store->OtherChars,
				CharacterStoreGetPrisonerId(store, data->Brush.Index2));
			DrawCharacterSimple(c, pos, DIRECTION_DOWN, false, false);
		}
		break;
	case OBJECTIVE_COLLECT:
		{
			const Pic *p = obj->u.Pickup->Pic;
			pos = Vec2iMinus(pos, Vec2iScaleDiv(p->size, 2));
			Blit(&gGraphicsDevice, p, pos);
		}
		break;
	case OBJECTIVE_DESTROY:
		DisplayMapItem(pos, obj->u.MapObject);
		break;
	default:
		assert(0 && "invalid objective type");
		break;
	}
}
예제 #27
0
static void AdjustYC(int *yc)
{
	Mission *mission = CampaignGetCurrentMission(&gCampaign);
	if (mission)
	{
		if (mission->Objectives.size)
		{
			*yc = CLAMP_OPPOSITE(
				*yc, 0, YC_OBJECTIVES + (int)mission->Objectives.size - 1);
		}
		else
		{
			*yc = CLAMP_OPPOSITE(*yc, 0, YC_OBJECTIVES);
		}
	}
	else
	{
		*yc = CLAMP_OPPOSITE(*yc, 0, YC_MISSIONINDEX);
	}
}
예제 #28
0
static char *MissionGetObjectiveDescription(UIObject *o, void *data)
{
	MissionObjectiveData *mData = data;
	Mission *m = CampaignGetCurrentMission(mData->Campaign);
	if (!m)
	{
		return NULL;
	}
	int i = mData->MissionObjectiveIndex;
	if ((int)m->Objectives.size <= i)
	{
		if (i == 0)
		{
			// first objective and mission has no objectives
			o->u.Textbox.IsEditable = false;
			return "-- mission objectives --";
		}
		return NULL;
	}
	o->u.Textbox.IsEditable = true;
	return ((const Objective *)CArrayGet(&m->Objectives, i))->Description;
}
예제 #29
0
static void MissionCheckObjectiveDescription(UIObject *o, void *data)
{
	MissionObjectiveData *mData = data;
	Mission *m = CampaignGetCurrentMission(mData->Campaign);
	if (!m)
	{
		o->IsVisible = false;
		return;
	}
	int i = mData->MissionObjectiveIndex;
	if ((int)m->Objectives.size <= i)
	{
		if (i == 0)
		{
			// first objective and mission has no objectives
			o->IsVisible = true;
			return;
		}
		o->IsVisible = false;
		return;
	}
	o->IsVisible = true;
}
static void CreateAddObjectiveSubObjs(UIObject *c, void *vData)
{
	EditorBrushAndCampaign *data = vData;
	Mission *m = CampaignGetCurrentMission(data->Campaign);
	// Check if the data is still the same; if so don't recreate the
	// child UI objects
	// This is because during the course of UI operations, this element
	// could be highlighted again; if we recreate then we invalidate
	// UI pointers.
	bool needToRecreate = false;
	int childIndex = 0;
	CA_FOREACH(const Objective, obj, m->Objectives)
		int secondaryCount = 1;
		const CharacterStore *store = &data->Campaign->Setting.characters;
		switch (obj->Type)
		{
		case OBJECTIVE_KILL:
			secondaryCount = (int)store->specialIds.size;
			break;
		case OBJECTIVE_COLLECT:
			break;
		case OBJECTIVE_DESTROY:
			break;
		case OBJECTIVE_RESCUE:
			secondaryCount = (int)store->prisonerIds.size;
			break;
		default:
			continue;
		}
		for (int j = 0; j < (int)secondaryCount; j++)
		{
			if ((int)c->Children.size <= childIndex)
			{
				needToRecreate = true;
				break;
			}
			UIObject *o2 = *(UIObject **)CArrayGet(&c->Children, childIndex);
			if (((EditorBrushAndCampaign *)o2->Data)->Brush.u.ItemIndex != _ca_index ||
				((EditorBrushAndCampaign *)o2->Data)->Brush.Index2 != j)
			{
				needToRecreate = true;
				break;
			}
			childIndex++;
		}
		if (needToRecreate)
		{
			break;
		}
	CA_FOREACH_END()
	if (!needToRecreate)
	{
		return;
	}

	// Recreate the child UI objects
	c->Highlighted = NULL;
	CA_FOREACH(UIObject *, obj, c->Children)
		UIObjectDestroy(*obj);
	CA_FOREACH_END()
	CArrayTerminate(&c->Children);
	CArrayInit(&c->Children, sizeof c);

	UIObject *o = UIObjectCreate(
		UITYPE_CUSTOM, 0,
		Vec2iZero(), Vec2iNew(TILE_WIDTH + 4, TILE_HEIGHT * 2 + 4));
	o->ChangeFunc = BrushSetBrushTypeAddObjective;
	o->u.CustomDrawFunc = DrawObjective;
	o->OnFocusFunc = ActivateEditorBrushAndCampaignBrush;
	o->OnUnfocusFunc = DeactivateEditorBrushAndCampaignBrush;
	Vec2i pos = Vec2iZero();
	CA_FOREACH(const Objective, obj, m->Objectives)
		int secondaryCount = 1;
		const CharacterStore *store = &data->Campaign->Setting.characters;
		switch (obj->Type)
		{
		case OBJECTIVE_KILL:
			secondaryCount = (int)store->specialIds.size;
			o->Size.y = TILE_HEIGHT * 2 + 4;
			break;
		case OBJECTIVE_COLLECT:
			o->Size.y = TILE_HEIGHT + 4;
			break;
		case OBJECTIVE_DESTROY:
			o->Size.y = TILE_HEIGHT * 2 + 4;
			break;
		case OBJECTIVE_RESCUE:
			secondaryCount = (int)store->prisonerIds.size;
			o->Size.y = TILE_HEIGHT * 2 + 4;
			break;
		default:
			continue;
		}
		for (int j = 0; j < (int)secondaryCount; j++)
		{
			UIObject *o2 = UIObjectCopy(o);
			CSTRDUP(o2->Tooltip, ObjectiveTypeStr(obj->Type));
			o2->IsDynamicData = true;
			CMALLOC(o2->Data, sizeof(EditorBrushAndCampaign));
			((EditorBrushAndCampaign *)o2->Data)->Brush.Brush =
				data->Brush.Brush;
			((EditorBrushAndCampaign *)o2->Data)->Campaign = data->Campaign;
			((EditorBrushAndCampaign *)o2->Data)->Brush.u.ItemIndex = _ca_index;
			((EditorBrushAndCampaign *)o2->Data)->Brush.Index2 = j;
			o2->Pos = pos;
			UIObjectAddChild(c, o2);
			pos.x += o->Size.x;
		}
		pos.x = 0;
		pos.y += o->Size.y;
	CA_FOREACH_END()
	UIObjectDestroy(o);
}