示例#1
0
/**
 *
 *  rct2: 0x006C42AC
 */
void user_string_free(rct_string_id id)
{
    if (!is_user_string_id(id))
        return;

    id %= MAX_USER_STRINGS;
    gUserStrings[id][0] = 0;
}
示例#2
0
void fix_duplicated_banners()
{
    // For each banner in the map, check if the banner index is in use already, and if so, create a new entry for it
    bool               activeBanners[Util::CountOf(gBanners)]{};
    rct_tile_element * tileElement;
    for (int y = 0; y < MAXIMUM_MAP_SIZE_TECHNICAL; y++)
    {
        for (int x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++)
        {
            tileElement = map_get_first_element_at(x, y);
            do
            {
                // TODO: Handle walls and large-scenery that use banner indices too. Large scenery can be tricky, as they occupy
                // multiple tiles that should both refer to the same banner index.
                if (tile_element_get_type(tileElement) == TILE_ELEMENT_TYPE_BANNER)
                {
                    uint8 bannerIndex = tileElement->properties.banner.index;
                    if (activeBanners[bannerIndex])
                    {
                        log_info(
                            "Duplicated banner with index %d found at x = %d, y = %d and z = %d.", bannerIndex, x, y,
                            tileElement->base_height);

                        // Banner index is already in use by another banner, so duplicate it
                        uint8 newBannerIndex = create_new_banner(GAME_COMMAND_FLAG_APPLY);
                        if (newBannerIndex == BANNER_NULL)
                        {
                            log_error("Failed to create new banner.");
                            continue;
                        }
                        Guard::Assert(activeBanners[newBannerIndex] == false);

                        // Copy over the original banner, but update the location
                        rct_banner & newBanner = gBanners[newBannerIndex];
                        newBanner              = gBanners[bannerIndex];
                        newBanner.x            = x;
                        newBanner.y            = y;

                        // Duplicate user string too
                        rct_string_id stringIdx = newBanner.string_idx;
                        if (is_user_string_id(stringIdx))
                        {
                            utf8 buffer[USER_STRING_MAX_LENGTH];
                            format_string(buffer, USER_STRING_MAX_LENGTH, stringIdx, nullptr);
                            rct_string_id newStringIdx = user_string_allocate(USER_STRING_DUPLICATION_PERMITTED, buffer);
                            if (newStringIdx == 0)
                            {
                                log_error("Failed to allocate user string for banner");
                                continue;
                            }
                            newBanner.string_idx = newStringIdx;
                        }

                        tileElement->properties.banner.index = newBannerIndex;
                    }

                    // Mark banner index as in-use
                    activeBanners[bannerIndex] = true;
                }
            } while (!tile_element_is_last_for_tile(tileElement++));
        }
    }
}
示例#3
0
static void twitch_parse_followers()
{
	struct AudienceMember {
		const char *name;
		bool isFollower;
		bool isInChat;
		bool isMod;
		bool exists;
		bool shouldTrack;
	};

	std::vector<AudienceMember> members;

	http_json_response *jsonResponse = _twitchJsonResponse;
	if (json_is_array(jsonResponse->root)) {
		int audienceCount = json_array_size(jsonResponse->root);
		for (int i = 0; i < audienceCount; i++) {
			json_t *audienceMember = json_array_get(jsonResponse->root, i);
			if (!json_is_object(audienceMember))
				continue;

			json_t *name = json_object_get(audienceMember, "name");
			json_t *isFollower = json_object_get(audienceMember, "isFollower");
			json_t *isInChat = json_object_get(audienceMember, "inChat");
			json_t *isMod = json_object_get(audienceMember, "isMod");

			AudienceMember member;
			member.name = json_string_value(name);
			member.isFollower = json_boolean_value(isFollower);
			member.isInChat = json_boolean_value(isInChat);
			member.isMod = json_boolean_value(isMod);
			member.exists = false;
			member.shouldTrack = false;

			if (member.name == NULL || member.name[0] == 0)
				continue;

			if (member.isInChat && gConfigTwitch.enable_chat_peep_tracking)
				member.shouldTrack = true;
			else if (member.isFollower && gConfigTwitch.enable_follower_peep_tracking)
				member.shouldTrack = true;

			if (gConfigTwitch.enable_chat_peep_names && member.isInChat)
				members.push_back(member);
			else if (gConfigTwitch.enable_follower_peep_names && member.isFollower)
				members.push_back(member);
		}

		uint16 spriteIndex;
		rct_peep *peep;
		char buffer[256];

		// Check what followers are already in the park
		FOR_ALL_GUESTS(spriteIndex, peep) {
			if (is_user_string_id(peep->name_string_idx)) {
				format_string(buffer, peep->name_string_idx, NULL);

				AudienceMember *member = NULL;
				for (size_t i = 0; i < members.size(); i++) {
					if (_strcmpi(buffer, members[i].name) == 0) {
						member = &members[i];
						members[i].exists = true;
						break;
					}
				}

				if (peep->peep_flags & PEEP_FLAGS_TWITCH) {
					if (member == NULL) {
						// Member no longer peep name worthy
						peep->peep_flags &= ~(PEEP_FLAGS_TRACKING | PEEP_FLAGS_TWITCH);

						// TODO set peep name back to number / real name
					} else {
						if (member->shouldTrack)
							peep->peep_flags |= (PEEP_FLAGS_TRACKING);
						else if (!member->shouldTrack)
							peep->peep_flags &= ~(PEEP_FLAGS_TRACKING);
					}
				} else if (member != NULL && !(peep->peep_flags & PEEP_FLAGS_LEAVING_PARK)) {
					// Peep with same name already exists but not twitch
					peep->peep_flags |= PEEP_FLAGS_TWITCH;
					if (member->shouldTrack)
						peep->peep_flags |= PEEP_FLAGS_TRACKING;
				}
			}
		}

		// Rename non-named peeps to followers that aren't currently in the park.
		if (members.size() > 0) {
			int memberIndex = -1;
			FOR_ALL_GUESTS(spriteIndex, peep) {
				int originalMemberIndex = memberIndex;
				for (size_t i = memberIndex + 1; i < members.size(); i++) {
					if (!members[i].exists) {
						memberIndex = i;
						break;
					}
				}
				if (originalMemberIndex == memberIndex)
					break;

				AudienceMember *member = &members[memberIndex];
				if (!is_user_string_id(peep->name_string_idx) && !(peep->peep_flags & PEEP_FLAGS_LEAVING_PARK)) {
					// Rename peep and add flags
					rct_string_id newStringId = user_string_allocate(4, member->name);
					if (newStringId != 0) {
						peep->name_string_idx = newStringId;
						peep->peep_flags |= PEEP_FLAGS_TWITCH;
						if (member->shouldTrack)
							peep->peep_flags |= PEEP_FLAGS_TRACKING;
					}
				} else {
					// Peep still yet to be found for member
					memberIndex--;
				}
			}