示例#1
0
文件: grafx.c 项目: cxong/cdogs-sdl
char *GrafxGetModeStr(void)
{
    static char buf[16];
    sprintf(buf, "%dx%d",
            ConfigGetInt(&gConfig, "Graphics.ResolutionWidth"),
            ConfigGetInt(&gConfig, "Graphics.ResolutionHeight"));
    return buf;
}
示例#2
0
void GraphicsConfigSetFromConfig(GraphicsConfig *c)
{
	GraphicsConfigSet(
		c,
		Vec2iNew(
			ConfigGetInt(&gConfig, "Graphics.ResolutionWidth"),
			ConfigGetInt(&gConfig, "Graphics.ResolutionHeight")),
		ConfigGetBool(&gConfig, "Graphics.Fullscreen"),
		ConfigGetInt(&gConfig, "Graphics.ScaleFactor"));
}
示例#3
0
文件: grafx.c 项目: cxong/cdogs-sdl
void GraphicsConfigSetFromConfig(GraphicsConfig *gc, Config *c)
{
    GraphicsConfigSet(
        gc,
        Vec2iNew(
            ConfigGetInt(c, "Graphics.ResolutionWidth"),
            ConfigGetInt(c, "Graphics.ResolutionHeight")),
        ConfigGetBool(c, "Graphics.Fullscreen"),
        ConfigGetInt(c, "Graphics.ScaleFactor"),
        (ScaleMode)ConfigGetEnum(c, "Graphics.ScaleMode"),
        ConfigGetInt(c, "Graphics.Brightness"));
}
示例#4
0
/*++

LogInit

    Initialize the logging subsystem.

Arguments:
    pool    - Main application pool, to create sub-pools from.

Return Values:
    Returns an APR status code.

--*/
apr_status_t
LogInit(
    apr_pool_t *pool
    )
{
    apr_status_t status;

    // Initialize static variables
    handle = NULL;
    maxLevel = LOG_LEVEL_OFF;

    if (ConfigGetInt(SectionGeneral, GeneralLogLevel, &maxLevel) != APR_SUCCESS || !maxLevel) {
        return APR_SUCCESS;
    }

    // Create a sub-pool for log message allocations
    status = apr_pool_create(&msgPool, pool);
    if (status != APR_SUCCESS) {
        return status;
    }

    // Open log file for writing
    return apr_file_open(&handle, LOG_FILE, APR_FOPEN_WRITE|
        APR_FOPEN_CREATE|APR_FOPEN_APPEND, APR_OS_DEFAULT, pool);
}
示例#5
0
static void DrawObjectiveHighlight(
	TTileItem *ti, Tile *tile, DrawBuffer *b, Vec2i offset)
{
	color_t color;
	if (ti->flags & TILEITEM_OBJECTIVE)
	{
		// Objective
		const int objective = ObjectiveFromTileItem(ti->flags);
		const Objective *o =
			CArrayGet(&gMission.missionData->Objectives, objective);
		if (o->Flags & OBJECTIVE_HIDDEN)
		{
			return;
		}
		if (!(o->Flags & OBJECTIVE_POSKNOWN) &&
			(tile->flags & MAPTILE_OUT_OF_SIGHT))
		{
			return;
		}
		color = o->color;
	}
	else if (ti->kind == KIND_PICKUP)
	{
		// Gun pickup
		const Pickup *p = CArrayGet(&gPickups, ti->id);
		if (!PickupIsManual(p))
		{
			return;
		}
		color = colorDarker;
	}
	else
	{
		return;
	}
	
	const Vec2i pos = Vec2iNew(
		ti->x - b->xTop + offset.x, ti->y - b->yTop + offset.y);
	const int pulsePeriod = ConfigGetInt(&gConfig, "Game.FPS");
	int alphaUnscaled =
		(gMission.time % pulsePeriod) * 255 / (pulsePeriod / 2);
	if (alphaUnscaled > 255)
	{
		alphaUnscaled = 255 * 2 - alphaUnscaled;
	}
	color.a = (Uint8)alphaUnscaled;
	if (ti->getPicFunc != NULL)
	{
		Vec2i picOffset;
		const Pic *pic = ti->getPicFunc(ti->id, &picOffset);
		BlitPicHighlight(
			&gGraphicsDevice, pic, Vec2iAdd(pos, picOffset), color);
	}
	else if (ti->kind == KIND_CHARACTER)
	{
		TActor *a = CArrayGet(&gActors, ti->id);
		ActorPics pics = GetCharacterPicsFromActor(a);
		DrawActorHighlight(&pics, pos, color);
	}
}
示例#6
0
文件: ai.c 项目: NSYXin/cdogs-sdl
void CreateEnemies(void)
{
    if (gCampaign.Setting.characters.baddieIds.size == 0)
    {
        return;
    }

    for (int i = 0;
            i < MAX(1, (gMission.missionData->EnemyDensity * ConfigGetInt(&gConfig, "Game.EnemyDensity")) / 100);
            i++)
    {
        NActorAdd aa = NActorAdd_init_default;
        aa.UID = ActorsGetNextUID();
        aa.CharId = CharacterStoreGetRandomBaddieId(
                        &gCampaign.Setting.characters);
        aa.FullPos = PlaceAwayFromPlayers(&gMap);
        aa.Direction = rand() % DIRECTION_COUNT;
        const Character *c =
            CArrayGet(&gCampaign.Setting.characters.OtherChars, aa.CharId);
        aa.Health = CharacterGetStartingHealth(c, true);
        GameEvent e = GameEventNew(GAME_EVENT_ACTOR_ADD);
        e.u.ActorAdd = aa;
        GameEventsEnqueue(&gGameEvents, e);
        gBaddieCount++;

        // Process the events that actually place the actors
        HandleGameEvents(&gGameEvents, NULL, NULL, NULL);
    }
}
示例#7
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;
}
示例#8
0
文件: draw.c 项目: NSYXin/cdogs-sdl
static void DrawObjectiveHighlight(
    TTileItem *ti, Tile *tile, DrawBuffer *b, Vec2i offset)
{
    if (!(ti->flags & TILEITEM_OBJECTIVE))
    {
        return;
    }
    int objective = ObjectiveFromTileItem(ti->flags);
    MissionObjective *mo =
        CArrayGet(&gMission.missionData->Objectives, objective);
    if (mo->Flags & OBJECTIVE_HIDDEN)
    {
        return;
    }
    if (!(mo->Flags & OBJECTIVE_POSKNOWN) &&
            (tile->flags & MAPTILE_OUT_OF_SIGHT))
    {
        return;
    }
    Vec2i pos = Vec2iNew(
                    ti->x - b->xTop + offset.x, ti->y - b->yTop + offset.y);
    const ObjectiveDef *o = CArrayGet(&gMission.Objectives, objective);
    color_t color = o->color;
    const int pulsePeriod = ConfigGetInt(&gConfig, "Game.FPS");
    int alphaUnscaled =
        (gMission.time % pulsePeriod) * 255 / (pulsePeriod / 2);
    if (alphaUnscaled > 255)
    {
        alphaUnscaled = 255 * 2 - alphaUnscaled;
    }
    color.a = (Uint8)alphaUnscaled;
    if (ti->getPicFunc != NULL)
    {
        Vec2i picOffset;
        const Pic *pic = ti->getPicFunc(ti->id, &picOffset);
        BlitPicHighlight(
            &gGraphicsDevice, pic, Vec2iAdd(pos, picOffset), color);
    }
    else if (ti->getActorPicsFunc != NULL)
    {
        ActorPics pics = ti->getActorPicsFunc(ti->id);
        // Do not highlight dead, dying or transparent characters
        if (!pics.IsDead && !pics.IsTransparent)
        {
            for (int i = 0; i < 3; i++)
            {
                if (PicIsNotNone(&pics.Pics[i]))
                {
                    BlitPicHighlight(
                        &gGraphicsDevice,
                        &pics.Pics[i], pos, color);
                }
            }
        }
    }
}
示例#9
0
文件: sounds.c 项目: NSYXin/cdogs-sdl
static void SoundPlayAtPosition(
	SoundDevice *device, Mix_Chunk *data, int distance, int bearing,
	const bool isMuffled)
{
	if (data == NULL)
	{
		return;
	}
	// If distance is very close, don't place any panning on it
	if (distance < DISTANCE_CLOSE) bearing = 0;
	if (isMuffled)
	{
		distance += OUT_OF_SIGHT_DISTANCE_PLUS;
	}
	distance /= 2;
	// Don't play anything if it's too distant
	// This means we don't waste sound channels
	if (distance > 255)
	{
		return;
	}

	if (!device->isInitialised)
	{
		return;
	}

	LOG(LM_SOUND, LL_TRACE, "distance(%d) bearing(%d)", distance, bearing);

	int channel;
	for (;;)
	{
		channel = Mix_PlayChannel(-1, data, 0);
		if (channel >= 0 || device->channels > 128)
		{
			break;
		}
		// Check if we cannot play the sound; allocate more channels
		device->channels *= 2;
		if (Mix_AllocateChannels(device->channels) != device->channels)
		{
			printf("Couldn't allocate channels!\n");
			return;
		}
		// When allocating new channels, need to reset their volume
		Mix_Volume(-1, ConfigGetInt(&gConfig, "Sound.SoundVolume"));
	}
	Mix_SetPosition(channel, (Sint16)bearing, (Uint8)distance);
	if (isMuffled)
	{
		if (!Mix_RegisterEffect(channel, MuffleEffect, NULL, NULL))
		{
			fprintf(stderr, "Mix_RegisterEffect: %s\n", Mix_GetError());
		}
	}
}
示例#10
0
static void CampaignChangeSeed(void *data, int d)
{
	UNUSED(data);
	if (gEventHandlers.keyboard.modState & KMOD_SHIFT)
	{
		d *= 10;
	}
	ConfigSetInt(
		&gConfig, "Game.RandomSeed",
		ConfigGetInt(&gConfig, "Game.RandomSeed") + d);
}
示例#11
0
InputKeys KeyLoadPlayerKeys(Config *c)
{
	InputKeys k;
	k.left = (SDL_Scancode)ConfigGetInt(c, "left");
	k.right = (SDL_Scancode)ConfigGetInt(c, "right");
	k.up = (SDL_Scancode)ConfigGetInt(c, "up");
	k.down = (SDL_Scancode)ConfigGetInt(c, "down");
	k.button1 = (SDL_Scancode)ConfigGetInt(c, "button1");
	k.button2 = (SDL_Scancode)ConfigGetInt(c, "button2");
	k.map = (SDL_Scancode)ConfigGetInt(c, "map");
	return k;
}
示例#12
0
文件: sounds.c 项目: NSYXin/cdogs-sdl
void SoundReconfigure(SoundDevice *s)
{
	s->isInitialised = false;

	if (Mix_AllocateChannels(s->channels) != s->channels)
	{
		printf("Couldn't allocate channels!\n");
		return;
	}

	Mix_Volume(-1, ConfigGetInt(&gConfig, "Sound.SoundVolume"));
	Mix_VolumeMusic(ConfigGetInt(&gConfig, "Sound.MusicVolume"));
	if (ConfigGetInt(&gConfig, "Sound.MusicVolume") > 0)
	{
		MusicResume(s);
	}
	else
	{
		MusicPause(s);
	}

	s->isInitialised = true;
}
示例#13
0
static void DrawThing(DrawBuffer *b, const TTileItem *t, const Vec2i offset)
{
	const Vec2i picPos = Vec2iNew(
		t->x - b->xTop + offset.x, t->y - b->yTop + offset.y);

	if (!Vec2iIsZero(t->ShadowSize))
	{
		DrawShadow(&gGraphicsDevice, picPos, t->ShadowSize);
	}

	if (t->CPicFunc)
	{
		CPicDrawContext c = t->CPicFunc(t->id);
		CPicDraw(b->g, &t->CPic, picPos, &c);
	}
	else if (t->getPicFunc)
	{
		Vec2i picOffset;
		const Pic *pic = t->getPicFunc(t->id, &picOffset);
		Blit(&gGraphicsDevice, pic, Vec2iAdd(picPos, picOffset));
	}
	else if (t->kind == KIND_CHARACTER)
	{
		TActor *a = CArrayGet(&gActors, t->id);
		ActorPics pics = GetCharacterPicsFromActor(a);
		DrawActorPics(&pics, picPos);
		// Draw weapon indicators
		DrawLaserSight(&pics, a, picPos);
	}
	else
	{
		(*(t->drawFunc))(picPos, &t->drawData);
	}

#ifdef DEBUG_DRAW_HITBOXES
	const int pulsePeriod = ConfigGetInt(&gConfig, "Game.FPS");
	int alphaUnscaled =
		(gMission.time % pulsePeriod) * 255 / (pulsePeriod / 2);
	if (alphaUnscaled > 255)
	{
		alphaUnscaled = 255 * 2 - alphaUnscaled;
	}
	color_t color = colorPurple;
	color.a = (Uint8)alphaUnscaled;
	DrawRectangle(
		&gGraphicsDevice, Vec2iMinus(picPos, Vec2iScaleDiv(t->size, 2)),
		t->size, color, DRAW_FLAG_LINE);
#endif
}
示例#14
0
文件: draw.c 项目: cxong/cdogs-sdl
static void DrawThing(
	DrawBuffer *b, const Thing *t, const struct vec2i offset)
{
	const struct vec2i picPos = svec2i_add(
		svec2i_subtract(
			svec2i_floor(svec2_add(t->Pos, t->drawShake)),
			svec2i(b->xTop, b->yTop)),
		offset);

	if (!svec2i_is_zero(t->ShadowSize))
	{
		DrawShadow(&gGraphicsDevice, picPos, t->ShadowSize);
	}

	if (t->CPicFunc)
	{
		t->CPicFunc(b->g, t->id, picPos);
	}
	else if (t->kind == KIND_CHARACTER)
	{
		TActor *a = CArrayGet(&gActors, t->id);
		ActorPics pics = GetCharacterPicsFromActor(a);
		DrawActorPics(&pics, picPos, false);
		// Draw weapon indicators
		DrawLaserSight(&pics, a, picPos);
	}
	else
	{
		(*(t->drawFunc))(picPos, &t->drawData);
	}

#ifdef DEBUG_DRAW_HITBOXES
	const int pulsePeriod = ConfigGetInt(&gConfig, "Game.FPS");
	int alphaUnscaled =
		(gMission.time % pulsePeriod) * 255 / (pulsePeriod / 2);
	if (alphaUnscaled > 255)
	{
		alphaUnscaled = 255 * 2 - alphaUnscaled;
	}
	color_t color = colorPurple;
	color.a = (Uint8)alphaUnscaled;
	DrawRectangle(
		&gGraphicsDevice, svec2i_subtract(picPos, svec2i_scale_divide(t->size, 2)),
		t->size, color, DRAW_FLAG_LINE);
#endif
}
示例#15
0
static bool MusicPlay(SoundDevice *device, const char *path)
{
	if (!device->isInitialised)
	{
		return true;
	}

	debug(D_NORMAL, "Attempting to play song: %s\n", path);

	if (path == NULL || strlen(path) == 0)
	{
		LOG(LM_SOUND, LL_WARN, "Attempting to play song with empty name");
		return false;
	}

	device->music = Mix_LoadMUS(path);
	if (device->music == NULL)
	{
		strcpy(device->musicErrorMessage, SDL_GetError());
		device->musicStatus = MUSIC_NOLOAD;
		return false;
	}

	debug(D_NORMAL, "Playing song: %s\n", path);

	Mix_PlayMusic(device->music, -1);
	device->musicStatus = MUSIC_PLAYING;

	if (ConfigGetInt(&gConfig, "Sound.MusicVolume") == 0)
	{
		MusicPause(device);
	}

	device->musicErrorMessage[0] = '\0';

	return true;
}
示例#16
0
void CampaignInit(CampaignOptions *campaign)
{
	memset(campaign, 0, sizeof *campaign);
	CampaignSettingInit(&campaign->Setting);
	campaign->seed = ConfigGetInt(&gConfig, "Game.RandomSeed");
}
示例#17
0
// Load Server configuration
void CLoginServer::LoadConfigurations( char* file )
{
    //Database
	Config.SQLServer.pcServer   = ConfigGetString ( file, "mysql_host", "localhost" );
	Config.SQLServer.pcDatabase = ConfigGetString ( file, "mysql_database", "roseon_beta" );
    Config.SQLServer.pcUserName = ConfigGetString ( file, "mysql_user", "root" );
	Config.SQLServer.pcPassword = ConfigGetString ( file, "mysql_pass", "" );
	Config.SQLServer.pcPort     = ConfigGetInt    ( file, "mysql_port", 3306 );
	//Server
    Config.ServerID             = ConfigGetInt    ( file, "serverid", 0 );
    Config.ServerType           = ConfigGetInt    ( file, "servertype", 0 );
    Config.LoginIP              = ConfigGetString ( file, "serverip", "127.0.0.1" );
	Config.LoginPort            = ConfigGetInt    ( file, "serverport", 29000 );
    Config.ServerName           = ConfigGetString ( file, "servername", "Loginserver" );
    Config.Connection           = ConfigGetInt    ( file, "connection", 0 );
    Config.LanIP                = ConfigGetString ( file, "lanip", "192.168.0.1" );
    Config.LanSubnet            = ConfigGetString ( file, "lansubmask", "192.168.0" );
	//Passwords
	Config.LoginPass            = ConfigGetInt    ( file, "loginpass", 123456 );
	Config.CharPass             = ConfigGetInt    ( file, "charpass", 123456 );
	Config.WorldPass            = ConfigGetInt    ( file, "worldpass", 123456 );
    //Login
    Config.MinimumAccessLevel   = ConfigGetInt    ( file, "accesslevel", 100 );
	Config.usethreads           = ConfigGetInt    ( file, "usethreads", 0 )==0?false:true;
    Config.CreateLoginAccount   = ConfigGetInt    ( file, "CreateLoginAccount", 0 )==0?false:true;
    Config.checkGameGuard       = ConfigGetInt    ( file, "checkGameGuard", 1)==0?false:true;
}
示例#18
0
文件: cdogs.c 项目: flags/cdogs-sdl
int main(int argc, char *argv[])
{
	int wait = 0;
	int controllerFlag = SDL_INIT_GAMECONTROLLER;
	credits_displayer_t creditsDisplayer;
	memset(&creditsDisplayer, 0, sizeof creditsDisplayer);
	custom_campaigns_t campaigns;
	memset(&campaigns, 0, sizeof campaigns);
	int forceResolution = 0;
	int err = 0;
	const char *loadCampaign = NULL;
	ENetAddress connectAddr;
	memset(&connectAddr, 0, sizeof connectAddr);

	srand((unsigned int)time(NULL));
	LogInit();

	PrintTitle();

	if (getenv("DEBUG") != NULL)
	{
		debug = true;
		char *dbg;
		if ((dbg = getenv("DEBUG_LEVEL")) != NULL)
		{
			debug_level = CLAMP(atoi(dbg), D_NORMAL, D_MAX);
		}
	}

	SetupConfigDir();
	gConfig = ConfigLoad(GetConfigFilePath(CONFIG_FILE));
	LoadCredits(&creditsDisplayer, colorPurple, colorDarker);
	AutosaveInit(&gAutosave);
	AutosaveLoad(&gAutosave, GetConfigFilePath(AUTOSAVE_FILE));

	if (enet_initialize() != 0)
	{
		LOG(LM_MAIN, LL_ERROR, "An error occurred while initializing ENet.");
		err = EXIT_FAILURE;
		goto bail;
	}
	NetClientInit(&gNetClient);

	// Print command line
	char buf[CDOGS_PATH_MAX];
	buf[0] = '\0';
	for (int i = 0; i < argc; i++)
	{
		strcat(buf, " ");
		// HACK: for OS X, blank out the -psn_XXXX argument so that it doesn't
		// break arg parsing
	#ifdef __APPLE__
		if (strncmp(argv[i], "-psn", strlen("-psn")) == 0)
		{
			argv[i] = "";
		}
	#endif
		strcat(buf, argv[i]);
	}
	LOG(LM_MAIN, LL_INFO, "Command line (%d args):%s", argc, buf);
	{
		struct option longopts[] =
		{
			{"fullscreen",	no_argument,		NULL,	'f'},
			{"scale",		required_argument,	NULL,	's'},
			{"screen",		required_argument,	NULL,	'c'},
			{"forcemode",	no_argument,		NULL,	'o'},
			{"nosound",		no_argument,		NULL,	'n'},
			{"nojoystick",	no_argument,		NULL,	'j'},
			{"wait",		no_argument,		NULL,	'w'},
			{"shakemult",	required_argument,	NULL,	'm'},
			{"connect",		required_argument,	NULL,	'x'},
			{"debug",		required_argument,	NULL,	'd'},
			{"log",			required_argument,	NULL,	1000},
			{"help",		no_argument,		NULL,	'h'},
			{0,				0,					NULL,	0}
		};
		int opt = 0;
		int idx = 0;
		while ((opt = getopt_long(argc, argv, "fs:c:onjwm:xd\0h", longopts, &idx)) != -1)
		{
			switch (opt)
			{
			case 'f':
				ConfigGet(&gConfig, "Graphics.Fullscreen")->u.Bool.Value = true;
				break;
			case 's':
				ConfigSetInt(&gConfig, "Graphics.ScaleFactor", atoi(optarg));
				break;
			case 'c':
				sscanf(optarg, "%dx%d",
					&ConfigGet(&gConfig, "Graphics.ResolutionWidth")->u.Int.Value,
					&ConfigGet(&gConfig, "Graphics.ResolutionHeight")->u.Int.Value);
				LOG(LM_MAIN, LL_DEBUG, "Video mode %dx%d set...",
					ConfigGetInt(&gConfig, "Graphics.ResolutionWidth"),
					ConfigGetInt(&gConfig, "Graphics.ResolutionHeight"));
				break;
			case 'o':
				forceResolution = 1;
				break;
			case 'n':
				LOG(LM_MAIN, LL_INFO, "Sound to 0 volume");
				ConfigGet(&gConfig, "Sound.SoundVolume")->u.Int.Value = 0;
				ConfigGet(&gConfig, "Sound.MusicVolume")->u.Int.Value = 0;
				break;
			case 'j':
				debug(D_NORMAL, "nojoystick\n");
				controllerFlag = 0;
				break;
			case 'w':
				wait = 1;
				break;
			case 'm':
				{
					ConfigGet(&gConfig, "Graphics.ShakeMultiplier")->u.Int.Value =
						MAX(atoi(optarg), 0);
					printf("Shake multiplier: %d\n",
						ConfigGetInt(&gConfig, "Graphics.ShakeMultiplier"));
				}
				break;
			case 'h':
				PrintHelp();
				goto bail;
			case 'd':
				// Set debug level
				debug = true;
				debug_level = CLAMP(atoi(optarg), D_NORMAL, D_MAX);
				break;
			case 1000:
				{
					char *comma = strchr(optarg, ',');
					if (comma)
					{
						// Set logging level for a single module
						// The module and level are comma separated
						*comma = '\0';
						const LogLevel ll = StrLogLevel(comma + 1);
						LogModuleSetLevel(StrLogModule(optarg), ll);
						printf("Logging %s at %s\n", optarg, LogLevelName(ll));
					}
					else
					{
						// Set logging level for all modules
						const LogLevel ll = StrLogLevel(optarg);
						for (int i = 0; i < (int)LM_COUNT; i++)
						{
							LogModuleSetLevel((LogModule)i, ll);
						}
						printf("Logging everything at %s\n", LogLevelName(ll));
					}
				}
				break;
			case 'x':
				if (enet_address_set_host(&connectAddr, optarg) != 0)
				{
					printf("Error: unknown host %s\n", optarg);
				}
				break;
			default:
				PrintHelp();
				// Ignore unknown arguments
				break;
			}
		}
		if (optind < argc)
		{
			// non-option ARGV-elements
			for (; optind < argc; optind++)
			{
				// Load campaign
				loadCampaign = argv[optind];
			}
		}
	}

	debug(D_NORMAL, "Initialising SDL...\n");
	const int sdlFlags =
		SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_HAPTIC;
	if (SDL_Init(sdlFlags | controllerFlag) != 0)
	{
		LOG(LM_MAIN, LL_ERROR, "Could not initialise SDL: %s", SDL_GetError());
		err = EXIT_FAILURE;
		goto bail;
	}
	if (SDLJBN_Init() != 0)
	{
		LOG(LM_MAIN, LL_ERROR, "Could not initialise SDLJBN: %s",
			SDLJBN_GetError());
		err = EXIT_FAILURE;
		goto bail;
	}
	SDL_EventState(SDL_DROPFILE, SDL_DISABLE);

	GetDataFilePath(buf, "");
	LOG(LM_MAIN, LL_INFO, "data dir(%s)", buf);
	LOG(LM_MAIN, LL_INFO, "config dir(%s)", GetConfigFilePath(""));

	SoundInitialize(&gSoundDevice, "sounds");
	if (!gSoundDevice.isInitialised)
	{
		LOG(LM_MAIN, LL_ERROR, "Sound initialization failed!");
	}

	LoadHighScores();

	debug(D_NORMAL, "Loading song lists...\n");
	LoadSongs();

	MusicPlayMenu(&gSoundDevice);

	EventInit(&gEventHandlers, NULL, NULL, true);
	NetServerInit(&gNetServer);

	if (wait)
	{
		printf("Press the enter key to continue...\n");
		getchar();
	}
	if (!PicManagerTryInit(
		&gPicManager, "graphics/cdogs.px", "graphics/cdogs2.px"))
	{
		LOG(LM_MAIN, LL_ERROR, "Failed to initialize graphics");
		err = EXIT_FAILURE;
		goto bail;
	}
	memcpy(origPalette, gPicManager.palette, sizeof(origPalette));
	GraphicsInit(&gGraphicsDevice, &gConfig);
	GraphicsInitialize(&gGraphicsDevice, forceResolution);
	if (!gGraphicsDevice.IsInitialized)
	{
		LOG(LM_MAIN, LL_WARN, "Cannot initialise video; trying default config");
		ConfigResetDefault(ConfigGet(&gConfig, "Graphics"));
		GraphicsInit(&gGraphicsDevice, &gConfig);
		GraphicsInitialize(&gGraphicsDevice, forceResolution);
	}
	if (!gGraphicsDevice.IsInitialized)
	{
		LOG(LM_MAIN, LL_ERROR, "Video didn't init!");
		err = EXIT_FAILURE;
		goto bail;
	}
	FontLoadFromJSON(&gFont, "graphics/font.png", "graphics/font.json");
	PicManagerLoadDir(&gPicManager, "graphics");

	ParticleClassesInit(&gParticleClasses, "data/particles.json");
	AmmoInitialize(&gAmmo, "data/ammo.json");
	BulletAndWeaponInitialize(
		&gBulletClasses, &gGunDescriptions,
		"data/bullets.json", "data/guns.json");
	CharacterClassesInitialize(&gCharacterClasses, "data/character_classes.json");
	LoadPlayerTemplates(
		&gPlayerTemplates, &gCharacterClasses, PLAYER_TEMPLATE_FILE);
	PickupClassesInit(
		&gPickupClasses, "data/pickups.json", &gAmmo, &gGunDescriptions);
	MapObjectsInit(&gMapObjects, "data/map_objects.json");
	CollisionSystemInit(&gCollisionSystem);
	CampaignInit(&gCampaign);
	LoadAllCampaigns(&campaigns);
	PlayerDataInit(&gPlayerDatas);

	GrafxMakeRandomBackground(
		&gGraphicsDevice, &gCampaign, &gMission, &gMap);

	debug(D_NORMAL, ">> Entering main loop\n");
	// Attempt to pre-load campaign if requested
	if (loadCampaign != NULL)
	{
		LOG(LM_MAIN, LL_INFO, "Loading campaign %s...", loadCampaign);
		gCampaign.Entry.Mode =
			strstr(loadCampaign, "/" CDOGS_DOGFIGHT_DIR "/") != NULL ?
			GAME_MODE_DOGFIGHT : GAME_MODE_NORMAL;
		CampaignEntry entry;
		if (!CampaignEntryTryLoad(&entry, loadCampaign, GAME_MODE_NORMAL) ||
			!CampaignLoad(&gCampaign, &entry))
		{
			LOG(LM_MAIN, LL_ERROR, "Failed to load campaign %s", loadCampaign);
		}
	}
	else if (connectAddr.host != 0)
	{
		if (NetClientTryScanAndConnect(&gNetClient, connectAddr.host))
		{
			ScreenWaitForCampaignDef();
		}
		else
		{
			printf("Failed to connect\n");
		}
	}
	LOG(LM_MAIN, LL_INFO, "Starting game");
	MainLoop(&creditsDisplayer, &campaigns);

bail:
	debug(D_NORMAL, ">> Shutting down...\n");
	MapTerminate(&gMap);
	PlayerDataTerminate(&gPlayerDatas);
	MapObjectsTerminate(&gMapObjects);
	PickupClassesTerminate(&gPickupClasses);
	ParticleClassesTerminate(&gParticleClasses);
	AmmoTerminate(&gAmmo);
	WeaponTerminate(&gGunDescriptions);
	BulletTerminate(&gBulletClasses);
	CharacterClassesTerminate(&gCharacterClasses);
	MissionOptionsTerminate(&gMission);
	NetClientTerminate(&gNetClient);
	atexit(enet_deinitialize);
	EventTerminate(&gEventHandlers);
	GraphicsTerminate(&gGraphicsDevice);

	PicManagerTerminate(&gPicManager);
	FontTerminate(&gFont);
	AutosaveSave(&gAutosave, GetConfigFilePath(AUTOSAVE_FILE));
	AutosaveTerminate(&gAutosave);
	ConfigSave(&gConfig, GetConfigFilePath(CONFIG_FILE));
	SavePlayerTemplates(&gPlayerTemplates, PLAYER_TEMPLATE_FILE);
	CArrayTerminate(&gPlayerTemplates);
	FreeSongs(&gMenuSongs);
	FreeSongs(&gGameSongs);
	SaveHighScores();
	UnloadCredits(&creditsDisplayer);
	UnloadAllCampaigns(&campaigns);
	CampaignTerminate(&gCampaign);
	SoundTerminate(&gSoundDevice, true);
	ConfigDestroy(&gConfig);

	SDLJBN_Quit();
	SDL_Quit();

	return err;
}
示例#19
0
void EventPoll(EventHandlers *handlers, Uint32 ticks)
{
	SDL_Event e;
	handlers->HasResolutionChanged = false;
	handlers->HasLostFocus = false;
	KeyPrePoll(&handlers->keyboard);
	MousePrePoll(&handlers->mouse);
	JoyPrePoll(&handlers->joysticks);
	SDL_free(handlers->DropFile);
	handlers->DropFile = NULL;
	// Don't process mouse events if focus just regained this cycle
	// This is to prevent bogus click events outside the window, e.g. in the
	// title bar
	bool regainedFocus = false;
	while (SDL_PollEvent(&e))
	{
		switch (e.type)
		{
		case SDL_KEYDOWN:
			if (e.key.repeat)
			{
				break;
			}
			KeyOnKeyDown(&handlers->keyboard, e.key.keysym);
			break;
		case SDL_KEYUP:
			KeyOnKeyUp(&handlers->keyboard, e.key.keysym);
			break;
		case SDL_TEXTINPUT:
			strcpy(handlers->keyboard.Typed, e.text.text);
			break;

		case SDL_CONTROLLERDEVICEADDED:
			{
				const SDL_JoystickID jid = JoyAdded(e.cdevice.which);
				if (jid == -1)
				{
					break;
				}
				// If there are players with unset devices,
				// set this controller to them
				CA_FOREACH(PlayerData, p, gPlayerDatas)
					if (p->inputDevice == INPUT_DEVICE_UNSET)
					{
						PlayerTrySetInputDevice(p, INPUT_DEVICE_JOYSTICK, jid);
						LOG(LM_INPUT, LL_INFO,
							"Joystick %d assigned to player %d", jid, p->UID);
						break;
					}
				CA_FOREACH_END()
			}
			break;

		case SDL_CONTROLLERDEVICEREMOVED:
			JoyRemoved(e.cdevice.which);
			// If there was a player using this joystick,
			// set their input device to nothing
			CA_FOREACH(PlayerData, p, gPlayerDatas)
				if (p->inputDevice == INPUT_DEVICE_JOYSTICK &&
					p->deviceIndex == e.cdevice.which)
				{
					PlayerTrySetInputDevice(p, INPUT_DEVICE_UNSET, 0);
					LOG(LM_INPUT, LL_WARN, "Joystick for player %d removed",
						p->UID);
					break;
				}
			CA_FOREACH_END()
			break;

		case SDL_CONTROLLERBUTTONDOWN:
			JoyOnButtonDown(e.cbutton);
			break;

		case SDL_CONTROLLERBUTTONUP:
			JoyOnButtonUp(e.cbutton);
			break;

		case SDL_CONTROLLERAXISMOTION:
			JoyOnAxis(e.caxis);
			break;

		case SDL_MOUSEBUTTONDOWN:
			if (regainedFocus) break;
			MouseOnButtonDown(&handlers->mouse, e.button.button);
			break;
		case SDL_MOUSEBUTTONUP:
			if (regainedFocus) break;
			MouseOnButtonUp(&handlers->mouse, e.button.button);
			break;
		case SDL_MOUSEWHEEL:
			if (regainedFocus) break;
			MouseOnWheel(&handlers->mouse, e.wheel.x, e.wheel.y);
			break;
		case SDL_WINDOWEVENT:
			switch (e.window.event)
			{
			case SDL_WINDOWEVENT_FOCUS_GAINED:
				regainedFocus = true;
				MusicSetPlaying(&gSoundDevice, true);
				break;
			case SDL_WINDOWEVENT_FOCUS_LOST:
				if (!gCampaign.IsClient && !ConfigGetBool(&gConfig, "StartServer"))
				{
					MusicSetPlaying(&gSoundDevice, false);
					handlers->HasLostFocus = true;
				}
				// Reset input handlers
				EventReset(
					handlers, handlers->mouse.cursor, handlers->mouse.trail);
				break;
			case SDL_WINDOWEVENT_SIZE_CHANGED:
				handlers->HasResolutionChanged = true;
				if (gGraphicsDevice.cachedConfig.IsEditor)
				{
					const int scale = ConfigGetInt(&gConfig, "Graphics.ScaleFactor");
					GraphicsConfigSet(
						&gGraphicsDevice.cachedConfig,
						Vec2iScaleDiv(
							Vec2iNew(e.window.data1, e.window.data2), scale),
						false,
						scale,
						gGraphicsDevice.cachedConfig.ScaleMode,
						gGraphicsDevice.cachedConfig.Brightness);
					GraphicsInitialize(&gGraphicsDevice);
				}
				break;
			default:
				// do nothing
				break;
			}
			break;
		case SDL_QUIT:
			handlers->HasQuit = true;
			break;
		case SDL_DROPFILE:
			handlers->DropFile = e.drop.file;
			break;
		default:
			break;
		}
	}
	KeyPostPoll(&handlers->keyboard, ticks);
	MousePostPoll(&handlers->mouse, ticks);
}
示例#20
0
static void AssignPlayerInputDevices(EventHandlers *handlers)
{
	bool assignedKeyboards[MAX_KEYBOARD_CONFIGS];
	bool assignedMouse = false;
	bool assignedJoysticks[MAX_JOYSTICKS];
	memset(assignedKeyboards, 0, sizeof assignedKeyboards);
	memset(assignedJoysticks, 0, sizeof assignedJoysticks);

	for (int i = 0; i < (int)gPlayerDatas.size; i++)
	{
		PlayerData *p = CArrayGet(&gPlayerDatas, i);
		if (!p->IsLocal)
		{
			continue;
		}
		if (p->inputDevice != INPUT_DEVICE_UNSET)
		{
			// Find all the assigned devices
			switch (p->inputDevice)
			{
			case INPUT_DEVICE_KEYBOARD:
				assignedKeyboards[p->deviceIndex] = true;
				break;
			case INPUT_DEVICE_MOUSE:
				assignedMouse = true;
				break;
			case INPUT_DEVICE_JOYSTICK:
				assignedJoysticks[p->deviceIndex] = true;
				break;
			default:
				// do nothing
				break;
			}
			continue;
		}

		// Try to assign devices to players
		// For each unassigned player, check if any device has button 1 pressed
		for (int j = 0; j < MAX_KEYBOARD_CONFIGS; j++)
		{
			char buf[256];
			sprintf(buf, "Input.PlayerKeys%d.button1", j);
			if (KeyIsPressed(&handlers->keyboard, ConfigGetInt(&gConfig, buf)) &&
				!assignedKeyboards[j])
			{
				PlayerSetInputDevice(p, INPUT_DEVICE_KEYBOARD, j);
				assignedKeyboards[j] = true;
				SoundPlay(&gSoundDevice, StrSound("hahaha"));
				break;
			}
		}
		if (MouseIsPressed(&handlers->mouse, SDL_BUTTON_LEFT) &&
			!assignedMouse)
		{
			PlayerSetInputDevice(p, INPUT_DEVICE_MOUSE, 0);
			assignedMouse = true;
			SoundPlay(&gSoundDevice, StrSound("hahaha"));
			continue;
		}
		for (int j = 0; j < handlers->joysticks.numJoys; j++)
		{
			if (JoyIsPressed(
				&handlers->joysticks.joys[j], CMD_BUTTON1) &&
				!assignedJoysticks[j])
			{
				PlayerSetInputDevice(p, INPUT_DEVICE_JOYSTICK, j);
				assignedJoysticks[j] = true;
				SoundPlay(&gSoundDevice, StrSound("hahaha"));
				break;
			}
		}
	}
}
示例#21
0
// Load Server configuration
void CCharServer::LoadConfigurations( char* file )
{
    //Database
    Config.SQLServer.pcServer   = ConfigGetString ( file, "mysql_host", "localhost" );
    Config.SQLServer.pcDatabase = ConfigGetString ( file, "mysql_database", "fate" );
    Config.SQLServer.pcUserName = ConfigGetString ( file, "mysql_user", "root" );
    Config.SQLServer.pcPassword = ConfigGetString ( file, "mysql_pass", "0urf4t3" );
    Config.SQLServer.pcPort     = ConfigGetInt    ( file, "mysql_port", 3306 );
    //Server
    Config.ServerID             = ConfigGetInt    ( file, "serverid", 1 );
    Config.ServerType           = ConfigGetInt    ( file, "servertype", 1 );
    Config.CharIP               = ConfigGetString ( file, "serverip", "209.141.43.6" );
    Config.CharPort             = ConfigGetInt    ( file, "serverport", 29100 );
    Config.ParentID             = ConfigGetInt    ( file, "parentid", 0 );
    Config.ServerName           = ConfigGetString ( file, "servername", "FableRose" );
    Config.Connection           = ConfigGetInt    ( file, "connection", 0 );
    Config.LanIP                = ConfigGetString ( file, "lanip", "192.168.1.20" );
    Config.LanSubnet            = ConfigGetString ( file, "lansubmask", "255.255.255.0" );
    //Char
    Config.usethreads           = ConfigGetInt    ( file, "usethreads", 0 )==0?false:true;
    Config.DeleteTime           = ConfigGetInt    ( file, "deletetime", 36000 );
    Config.MinimumAccessLevel   = ConfigGetInt    ( file, "accesslevel", 100 );
    //Password
    Config.LoginPass            = ConfigGetInt    ( file, "loginpass", 123456 );
    Config.CharPass             = ConfigGetInt    ( file, "charpass", 123456 );
    Config.WorldPass            = ConfigGetInt    ( file, "worldpass", 123456 );
}
示例#22
0
		Config config1, config2;
		GIVEN("two configs")
		GIVEN_END

		WHEN("I load them both with defaults")
			// Note: default loaded before loading from file
			config1 = ConfigLoad(NULL);
			config2 = ConfigLoad(NULL);
		WHEN_END

		THEN("the two configs should have the same values")
			SHOULD_INT_EQUAL(
				ConfigGetBool(&config1, "Game.FriendlyFire"),
				ConfigGetBool(&config2, "Game.FriendlyFire"));
			SHOULD_INT_EQUAL(
				ConfigGetInt(&config1, "Graphics.Brightness"),
				ConfigGetInt(&config2, "Graphics.Brightness"));
		THEN_END
	}
	SCENARIO_END
FEATURE_END

FEATURE(2, "Save and load")
	SCENARIO("Save and load a JSON config file")
	{
		Config config1, config2;
		GIVEN("a config file with some values, and I save the config to a JSON file")
			config1 = ConfigLoad(NULL);
			ConfigGet(&config1, "Game.FriendlyFire")->u.Bool.Value = true;
			ConfigGet(&config1, "Graphics.Brightness")->u.Int.Value = 5;
			ConfigSave(&config1, "tmp");
示例#23
0
// Load Server configuration
void CWorldServer::LoadConfigurations( char* file )
{
    //Database
	Config.SQLServer.pcServer   = ConfigGetString ( file, "mysql_host", "localhost" );
	Config.SQLServer.pcDatabase = ConfigGetString ( file, "mysql_database", "roseon_beta" );
    Config.SQLServer.pcUserName = ConfigGetString ( file, "mysql_user", "root" );
	Config.SQLServer.pcPassword = ConfigGetString ( file, "mysql_pass", "" );
	Config.SQLServer.pcPort     = ConfigGetInt    ( file, "mysql_port", 3306 );
    //Server
	Config.ServerID             = ConfigGetInt    ( file, "serverid", 1 );
	Config.ServerType           = ConfigGetInt    ( file, "servertype", 2 );
	Config.WorldPort            = ConfigGetInt    ( file, "serverport", 29200 );
	Config.WorldIP              = ConfigGetString ( file, "serverip", "127.0.0.1" );
	Config.ParentID             = ConfigGetInt    ( file, "parentid", 1 );
	Config.ServerName           = ConfigGetString ( file, "servername", "Channel" );
    Config.MaxConnections       = ConfigGetInt    ( file, "maxconnections", 100 );
    Config.Connection           = ConfigGetInt    ( file, "connection", 0 );
    Config.LanIP                = ConfigGetString ( file, "lanip", "192.168.0.1" );
    Config.LanSubnet            = ConfigGetString ( file, "lansubmask", "192.168.0" );
    //World
    Config.MinimumAccessLevel   = ConfigGetInt    ( file, "minimal_access_level", 100 );
	Config.usethreads           = ConfigGetInt    ( file, "usethreads", 0 )==0?false:true;
	Config.WELCOME_MSG          = ConfigGetString ( file, "welcome_msg", "Welcome to Rose Online" );

    Log (MSG_INFO, "osRose - http://forum.dev-osrose.com");

    //Password
	Config.LoginPass            = ConfigGetInt    ( file, "loginpass", 123456 );
	Config.CharPass             = ConfigGetInt    ( file, "charpass", 123456 );
	Config.WorldPass            = ConfigGetInt    ( file, "worldpass", 123456 );
    if(Config.AUTOSAVE==1)
        Log( MSG_INFO, "Autosaving Every %i minutes", Config.SAVETIME/60 );

    LoadCommandLevels();
}
示例#24
0
// Load Server configuration
void CWorldServer::LoadConfigurations( char* file )
{
    //Database
	Config.SQLServer.pcServer   = ConfigGetString ( file, "mysql_host", "localhost" );
	Config.SQLServer.pcDatabase = ConfigGetString ( file, "mysql_database", "roseon_beta" );
    Config.SQLServer.pcUserName = ConfigGetString ( file, "mysql_user", "root" );    
	Config.SQLServer.pcPassword = ConfigGetString ( file, "mysql_pass", "" );
	Config.SQLServer.pcPort     = ConfigGetInt    ( file, "mysql_port", 3306 );		
    //Server	
	Config.ServerID             = ConfigGetInt    ( file, "serverid", 1 );    
	Config.ServerType           = ConfigGetInt    ( file, "servertype", 2 );    
	Config.WorldPort            = ConfigGetInt    ( file, "serverport", 29200 );	
	Config.WorldIP              = ConfigGetString ( file, "serverip", "127.0.0.1" ); 	
	Config.ParentID             = ConfigGetInt    ( file, "parentid", 1 );
	Config.ServerName           = ConfigGetString ( file, "servername", "Channel" );
    Config.MaxConnections       = ConfigGetInt    ( file, "maxconnections", 100 );    
    Config.Connection           = ConfigGetInt    ( file, "connection", 0 );        
    Config.LanIP                = ConfigGetString ( file, "lanip", "192.168.0.1" );
    Config.LanSubnet            = ConfigGetString ( file, "lansubmask", "192.168.0" );
    //World
    Config.MinimumAccessLevel   = ConfigGetInt    ( file, "minimal_access_level", 100 );    
	Config.usethreads           = ConfigGetInt    ( file, "usethreads", 0 )==0?false:true;
	Config.EXP_RATE             = ConfigGetInt    ( file, "exp_rate", 10 );
	Config.DROP_RATE            = ConfigGetInt    ( file, "drop_rate", 1 );
    Config.DROP_TYPE            = ConfigGetInt    ( file, "drop_type", 2 );  	
	Config.ZULY_RATE            = ConfigGetInt    ( file, "zuly_rate", 1 );
	Config.WELCOME_MSG          = ConfigGetString ( file, "welcome_msg", "Welcome to Rose Online" );
    Config.AUTOSAVE             = ConfigGetInt    ( file, "autosave", 0 );	
	Config.SAVETIME             = ConfigGetInt    ( file, "savetime", 3600 );	    
    Config.MapDelay             = ConfigGetInt    ( file, "mapdelay", 10 );  
    Config.WorldDelay           = ConfigGetInt    ( file, "worlddelay", 200 );  
    Config.VisualDelay          = ConfigGetInt    ( file, "visualdelay", 500 );
    Config.Partygap             = ConfigGetInt    ( file, "partygap", 10 ); 
    Config.MaxStat              = ConfigGetInt    ( file, "maxstat", 254 ); 
    Config.FairyMode            = ConfigGetInt    ( file, "fairy", 1 );
    Config.FairyStay            = ConfigGetInt    ( file, "fairystay", 20 ); 
    Config.FairyWait            = ConfigGetInt    ( file, "fairywait", 15 );  
    Config.FairyMax             = ConfigGetInt    ( file, "fairymax", 0); 
    Config.FairyTestMode        = ConfigGetInt    ( file, "fairytestmode", 1);
    Config.PlayerDmg            = ConfigGetInt    ( file, "playerdmg", 120);                 
    Config.MonsterDmg           = ConfigGetInt    ( file, "monsterdmg", 100);
    Config.Cfmode               = ConfigGetInt    ( file, "cfmode", 0);
    Config.osRoseVer             = ConfigGetInt    ( file, "osRoseVer", 79);
    Config.testgrid             = ConfigGetInt    ( file, "testgrid", 0); //LMA: maps tests grids (0=usual, 1=grid)
    Config.jrose             = ConfigGetInt    ( file, "jrose", 0); //LMA: Special code for jRose handling (163)
        
    Log (MSG_INFO, "osRose Revision %i", Config.osRoseVer );
    
    //LMA: jRose.    
    if(Config.jrose==1)
       Log (MSG_INFO, "Handling ONLY jRose client.");
    else
       Log (MSG_INFO, "Handling ONLY RoseNA client.");    
        
    //Password
	Config.LoginPass            = ConfigGetInt    ( file, "loginpass", 123456 );		
	Config.CharPass             = ConfigGetInt    ( file, "charpass", 123456 );	
	Config.WorldPass            = ConfigGetInt    ( file, "worldpass", 123456 );
    if(Config.AUTOSAVE==1)
        Log( MSG_INFO, "Autosaving Every %i minutes", Config.SAVETIME/60 );	

    LoadCommandLevels();    
}
示例#25
0
文件: ai.c 项目: NSYXin/cdogs-sdl
void CommandBadGuys(int ticks)
{
    int count = 0;
    int delayModifier;
    int rollLimit;

    switch (ConfigGetEnum(&gConfig, "Game.Difficulty"))
    {
    case DIFFICULTY_VERYEASY:
        delayModifier = 4;
        rollLimit = 300;
        break;
    case DIFFICULTY_EASY:
        delayModifier = 2;
        rollLimit = 200;
        break;
    case DIFFICULTY_HARD:
        delayModifier = 1;
        rollLimit = 75;
        break;
    case DIFFICULTY_VERYHARD:
        delayModifier = 1;
        rollLimit = 50;
        break;
    default:
        delayModifier = 1;
        rollLimit = 100;
        break;
    }

    CA_FOREACH(TActor, actor, gActors)
    if (!actor->isInUse)
    {
        continue;
    }
    const CharBot *bot = ActorGetCharacter(actor)->bot;
    if (!(actor->PlayerUID >= 0 || (actor->flags & FLAGS_PRISONER)))
    {
        if ((actor->flags & (FLAGS_VICTIM | FLAGS_GOOD_GUY)) != 0)
        {
            gAreGoodGuysPresent = 1;
        }

        count++;
        int cmd = 0;

        // Wake up if it can see a player
        if ((actor->flags & FLAGS_SLEEPING) &&
                actor->aiContext->Delay == 0)
        {
            if (CanSeeAPlayer(actor))
            {
                actor->flags &= ~FLAGS_SLEEPING;
                ActorSetAIState(actor, AI_STATE_NONE);
            }
            actor->aiContext->Delay = bot->actionDelay * delayModifier;
            // Randomly change direction
            int newDir = (int)actor->direction + ((rand() % 2) * 2 - 1);
            if (newDir < (int)DIRECTION_UP)
            {
                newDir = (int)DIRECTION_UPLEFT;
            }
            if (newDir == (int)DIRECTION_COUNT)
            {
                newDir = (int)DIRECTION_UP;
            }
            cmd = DirectionToCmd((int)newDir);
        }
        // Go to sleep if the player's too far away
        if (!(actor->flags & FLAGS_SLEEPING) &&
                actor->aiContext->Delay == 0 &&
                !(actor->flags & FLAGS_AWAKEALWAYS))
        {
            if (!IsCloseToPlayer(actor->Pos, (40 * 16) << 8))
            {
                actor->flags |= FLAGS_SLEEPING;
                ActorSetAIState(actor, AI_STATE_IDLE);
            }
        }

        if (!actor->dead && !(actor->flags & FLAGS_SLEEPING))
        {
            bool bypass = false;
            const int roll = rand() % rollLimit;
            if (actor->flags & FLAGS_FOLLOWER)
            {
                if (IsCloseToPlayer(actor->Pos, 32 << 8))
                {
                    cmd = 0;
                    ActorSetAIState(actor, AI_STATE_IDLE);
                }
                else
                {
                    cmd = AIGoto(
                              actor, AIGetClosestPlayerPos(actor->Pos), true);
                    ActorSetAIState(actor, AI_STATE_FOLLOW);
                }
            }
            else if (!!(actor->flags & FLAGS_SNEAKY) &&
                     !!(actor->flags & FLAGS_VISIBLE) &&
                     DidPlayerShoot())
            {
                cmd = AIHuntClosest(actor) | CMD_BUTTON1;
                if (actor->flags & FLAGS_RUNS_AWAY)
                {
                    // Turn back and shoot for running away characters
                    cmd = AIReverseDirection(cmd);
                }
                bypass = true;
                ActorSetAIState(actor, AI_STATE_HUNT);
            }
            else if (actor->flags & FLAGS_DETOURING)
            {
                cmd = BrightWalk(actor, roll);
                ActorSetAIState(actor, AI_STATE_TRACK);
            }
            else if (actor->aiContext->Delay > 0)
            {
                cmd = actor->lastCmd & ~CMD_BUTTON1;
            }
            else
            {
                if (roll < bot->probabilityToTrack)
                {
                    cmd = AIHuntClosest(actor);
                    ActorSetAIState(actor, AI_STATE_HUNT);
                }
                else if (roll < bot->probabilityToMove)
                {
                    cmd = DirectionToCmd(rand() & 7);
                    ActorSetAIState(actor, AI_STATE_TRACK);
                }
                else
                {
                    cmd = 0;
                }
                actor->aiContext->Delay = bot->actionDelay * delayModifier;
            }
            if (!bypass)
            {
                if (WillFire(actor, roll))
                {
                    cmd |= CMD_BUTTON1;
                    if (!!(actor->flags & FLAGS_FOLLOWER) &&
                            (actor->flags & FLAGS_GOOD_GUY))
                    {
                        // Shoot in a random direction away
                        for (int j = 0; j < 10; j++)
                        {
                            direction_e d =
                                (direction_e)(rand() % DIRECTION_COUNT);
                            if (!IsFacingPlayer(actor, d))
                            {
                                cmd = DirectionToCmd(d) | CMD_BUTTON1;
                                break;
                            }
                        }
                    }
                    if (actor->flags & FLAGS_RUNS_AWAY)
                    {
                        // Turn back and shoot for running away characters
                        cmd |= AIReverseDirection(AIHuntClosest(actor));
                    }
                    ActorSetAIState(actor, AI_STATE_HUNT);
                }
                else
                {
                    if ((actor->flags & FLAGS_VISIBLE) == 0)
                    {
                        // I think this is some hack to make sure invisible enemies don't fire so much
                        ActorGetGun(actor)->lock = 40;
                    }
                    if (cmd && !IsDirectionOK(actor, CmdToDirection(cmd)) &&
                            (actor->flags & FLAGS_DETOURING) == 0)
                    {
                        Detour(actor);
                        cmd = 0;
                        ActorSetAIState(actor, AI_STATE_TRACK);
                    }
                }
            }
        }
        actor->aiContext->Delay =
            MAX(0, actor->aiContext->Delay - ticks);
        CommandActor(actor, cmd, ticks);
    }
    else if ((actor->flags & FLAGS_PRISONER) != 0)
    {
        CommandActor(actor, 0, ticks);
    }
    CA_FOREACH_END()
    if (gMission.missionData->Enemies.size > 0 &&
            gMission.missionData->EnemyDensity > 0 &&
            count < MAX(1, (gMission.missionData->EnemyDensity * ConfigGetInt(&gConfig, "Game.EnemyDensity")) / 100))
    {
        NActorAdd aa = NActorAdd_init_default;
        aa.UID = ActorsGetNextUID();
        aa.CharId = CharacterStoreGetRandomBaddieId(
                        &gCampaign.Setting.characters);
        aa.Direction = rand() % DIRECTION_COUNT;
        const Character *c =
            CArrayGet(&gCampaign.Setting.characters.OtherChars, aa.CharId);
        aa.Health = CharacterGetStartingHealth(c, true);
        aa.FullPos = PlaceAwayFromPlayers(&gMap);
        GameEvent e = GameEventNew(GAME_EVENT_ACTOR_ADD);
        e.u.ActorAdd = aa;
        GameEventsEnqueue(&gGameEvents, e);
        gBaddieCount++;
    }
}
示例#26
0
文件: grafx.c 项目: cxong/cdogs-sdl
void GraphicsInitialize(GraphicsDevice *g)
{
    if (g->IsInitialized && !g->cachedConfig.RestartFlags)
    {
        return;
    }

    if (!g->IsWindowInitialized)
    {
        char buf[CDOGS_PATH_MAX];
        GetDataFilePath(buf, "cdogs_icon.bmp");
        g->icon = IMG_Load(buf);
        AddSupportedGraphicsModes(g);
        g->IsWindowInitialized = true;
    }

    g->IsInitialized = false;

    const int w = g->cachedConfig.Res.x;
    const int h = g->cachedConfig.Res.y;

    const bool initRenderer =
        !!(g->cachedConfig.RestartFlags & RESTART_RESOLUTION);
    const bool initTextures =
        !!(g->cachedConfig.RestartFlags &
           (RESTART_RESOLUTION | RESTART_SCALE_MODE));
    const bool initBrightness =
        !!(g->cachedConfig.RestartFlags &
           (RESTART_RESOLUTION | RESTART_SCALE_MODE | RESTART_BRIGHTNESS));

    if (initRenderer)
    {
        Uint32 sdlFlags = SDL_WINDOW_RESIZABLE;
        if (g->cachedConfig.Fullscreen)
        {
            sdlFlags |= SDL_WINDOW_FULLSCREEN;
        }

        LOG(LM_GFX, LL_INFO, "graphics mode(%dx%d %dx)",
            w, h, g->cachedConfig.ScaleFactor);
        // Get the previous window's size and recreate it
        Vec2i windowSize = Vec2iNew(
                               w * g->cachedConfig.ScaleFactor, h * g->cachedConfig.ScaleFactor);
        if (g->window)
        {
            SDL_GetWindowSize(g->window, &windowSize.x, &windowSize.y);
        }
        LOG(LM_GFX, LL_DEBUG, "destroying previous renderer");
        SDL_DestroyTexture(g->screen);
        SDL_DestroyTexture(g->bkg);
        SDL_DestroyTexture(g->brightnessOverlay);
        SDL_DestroyRenderer(g->renderer);
        SDL_FreeFormat(g->Format);
        SDL_DestroyWindow(g->window);
        LOG(LM_GFX, LL_DEBUG, "creating window %dx%d flags(%X)",
            windowSize.x, windowSize.y, sdlFlags);
        if (SDL_CreateWindowAndRenderer(
                    windowSize.x, windowSize.y, sdlFlags,
                    &g->window, &g->renderer) == -1 ||
                g->window == NULL || g->renderer == NULL)
        {
            LOG(LM_GFX, LL_ERROR, "cannot create window or renderer: %s",
                SDL_GetError());
            return;
        }
        char title[32];
        sprintf(title, "C-Dogs SDL %s%s",
                g->cachedConfig.IsEditor ? "Editor " : "",
                CDOGS_SDL_VERSION);
        LOG(LM_GFX, LL_DEBUG, "setting title(%s) and icon", title);
        SDL_SetWindowTitle(g->window, title);
        SDL_SetWindowIcon(g->window, g->icon);
        g->Format = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888);

        if (SDL_RenderSetLogicalSize(g->renderer, w, h) != 0)
        {
            LOG(LM_GFX, LL_ERROR, "cannot set renderer logical size: %s",
                SDL_GetError());
            return;
        }

        GraphicsSetBlitClip(
            g, 0, 0, g->cachedConfig.Res.x - 1, g->cachedConfig.Res.y - 1);
    }

    if (initTextures)
    {
        if (!initRenderer)
        {
            SDL_DestroyTexture(g->screen);
            SDL_DestroyTexture(g->bkg);
            SDL_DestroyTexture(g->brightnessOverlay);
        }

        // Set render scale mode
        const char *renderScaleQuality = "nearest";
        switch ((ScaleMode)ConfigGetEnum(&gConfig, "Graphics.ScaleMode"))
        {
        case SCALE_MODE_NN:
            renderScaleQuality = "nearest";
            break;
        case SCALE_MODE_BILINEAR:
            renderScaleQuality = "linear";
            break;
        default:
            CASSERT(false, "unknown scale mode");
            break;
        }
        LOG(LM_GFX, LL_DEBUG, "setting scale quality %s", renderScaleQuality);
        if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, renderScaleQuality))
        {
            LOG(LM_GFX, LL_WARN, "cannot set render quality hint: %s",
                SDL_GetError());
        }

        g->screen = CreateTexture(
                        g->renderer, SDL_TEXTUREACCESS_STREAMING, Vec2iNew(w, h),
                        SDL_BLENDMODE_BLEND, 255);
        if (g->screen == NULL)
        {
            return;
        }

        CFREE(g->buf);
        CCALLOC(g->buf, GraphicsGetMemSize(&g->cachedConfig));
        g->bkg = CreateTexture(
                     g->renderer, SDL_TEXTUREACCESS_STATIC, Vec2iNew(w, h),
                     SDL_BLENDMODE_NONE, 255);
        if (g->bkg == NULL)
        {
            return;
        }
    }

    if (initBrightness)
    {
        if (!initRenderer && !initTextures)
        {
            SDL_DestroyTexture(g->brightnessOverlay);
        }

        const int brightness = ConfigGetInt(&gConfig, "Graphics.Brightness");
        // Alpha is approximately 50% max
        const Uint8 alpha = (Uint8)(brightness > 0 ? brightness : -brightness) * 13;
        g->brightnessOverlay = CreateTexture(
                                   g->renderer, SDL_TEXTUREACCESS_STATIC, Vec2iNew(w, h),
                                   SDL_BLENDMODE_BLEND, alpha);
        if (g->brightnessOverlay == NULL)
        {
            return;
        }
        const color_t overlayColour = brightness > 0 ? colorWhite : colorBlack;
        DrawRectangle(g, Vec2iZero(), g->cachedConfig.Res, overlayColour, 0);
        SDL_UpdateTexture(
            g->brightnessOverlay, NULL, g->buf,
            g->cachedConfig.Res.x * sizeof(Uint32));
        memset(g->buf, 0, GraphicsGetMemSize(&g->cachedConfig));
        g->cachedConfig.Brightness = brightness;
    }

    g->IsInitialized = true;
    g->cachedConfig.Res.x = w;
    g->cachedConfig.Res.y = h;
    g->cachedConfig.RestartFlags = 0;
}
示例#27
0
// Load commands from commands.ini [by Paul_T]
void CWorldServer::LoadCommandLevels( void )
{
    Config.Command_Ani = ConfigGetInt    ( "commands.ini", "ani", 299 );
    Config.Command_Ann = ConfigGetInt    ( "commands.ini", "ann", 299 );
    Config.Command_Ban = ConfigGetInt    ( "commands.ini", "ban", 299 );
    Config.Command_Cha = ConfigGetInt    ( "commands.ini", "cha", 299 );
    Config.Command_ChangeFairyWait = ConfigGetInt    ( "commands.ini", "changefairywait", 299 );
    Config.Command_ChangeFairyStay = ConfigGetInt    ( "commands.ini", "changefairystay", 299 );
    Config.Command_ChangeFairyTestMode = ConfigGetInt    ( "commands.ini", "changefairytestmode", 299 );
    Config.Command_Class = ConfigGetInt    ( "commands.ini", "class", 299 );
    Config.Command_Convert = ConfigGetInt    ( "commands.ini", "convert", 299 );
    Config.Command_Cfmode = ConfigGetInt    ( "commands.ini", "cfmode", 299 ); 
    Config.Command_DelSpawn = ConfigGetInt    ( "commands.ini", "delspawn", 299 );
    Config.Command_DQuest = ConfigGetInt    ( "commands.ini", "dquest", 299 );
    Config.Command_Drop = ConfigGetInt    ( "commands.ini", "drop", 299 );
    Config.Command_DSpawn = ConfigGetInt    ( "commands.ini", "dspawn", 299 );
    Config.Command_ESpawn = ConfigGetInt    ( "commands.ini", "espawn", 299 );
    Config.Command_Exp = ConfigGetInt    ( "commands.ini", "exp", 299 );
    Config.Command_Face = ConfigGetInt    ( "commands.ini", "face", 299 );
    Config.Command_Give2 = ConfigGetInt    ( "commands.ini", "give2", 299 );
    Config.Command_GiveClanRp = ConfigGetInt    ( "commands.ini", "giveclanrp", 299 );       //Reward points
    Config.Command_GiveFairy = ConfigGetInt    ( "commands.ini", "givefairy", 299 );
    Config.Command_GiveZuly = ConfigGetInt    ( "commands.ini", "givezuly", 299 );
    Config.Command_GmList = ConfigGetInt ( "commands.ini", "gmlist", 299 );
    Config.Command_Go = ConfigGetInt    ( "commands.ini", "go", 299 );
    Config.Command_Goto = ConfigGetInt    ( "commands.ini", "goto", 299 );
    Config.Command_GoToMap = ConfigGetInt    ( "commands.ini", "gotomap", 299 );
    Config.Command_Hair = ConfigGetInt    ( "commands.ini", "hair", 299 );
    Config.Command_Heal = ConfigGetInt    ( "commands.ini", "heal", 299 );
    Config.Command_Here = ConfigGetInt    ( "commands.ini", "here", 299 );
    Config.Command_Hide = ConfigGetInt    ( "commands.ini", "hide", 299 );
    Config.Command_Info = ConfigGetInt    ( "commands.ini", "info", 299 );
    Config.Command_IQuest = ConfigGetInt    ( "commands.ini", "iquest", 299 );
    Config.Command_Item = ConfigGetInt    ( "commands.ini", "item", 299 );
    Config.Command_AllSkill = ConfigGetInt ( "commands.ini", "allskill", 299 );
    Config.Command_DelSkills = ConfigGetInt ( "commands.ini", "delskills", 299 );
    Config.Command_Job = ConfigGetInt    ( "commands.ini", "job", 299 );
    Config.Command_Kick = ConfigGetInt    ( "commands.ini", "kick", 299 );
    Config.Command_KillInRange = ConfigGetInt    ( "commands.ini", "killinrange", 299 );
    Config.Command_Level = ConfigGetInt    ( "commands.ini", "level", 299 );
    Config.Command_LevelUp = ConfigGetInt    ( "commands.ini", "levelup", 299 );
    Config.Command_ManageFairy = ConfigGetInt    ( "commands.ini", "managefairy", 299 );
    Config.Command_HurtHim = ConfigGetInt    ( "commands.ini", "hurthim", 299 );
    Config.Command_Mdmg = ConfigGetInt    ( "commands.ini", "mdmg", 299 );
    Config.Command_Mon = ConfigGetInt    ( "commands.ini", "mon", 299 );
    Config.Command_Mon2 = ConfigGetInt    ( "commands.ini", "mon2", 299 );
    Config.Command_Monster    = ConfigGetInt    ( "commands.ini", "monster", 299 );
    Config.Command_Move = ConfigGetInt    ( "commands.ini", "move", 299 );
    Config.Command_Moveto = ConfigGetInt    ( "commands.ini", "moveto", 299 );
    Config.Command_Mute = ConfigGetInt    ( "commands.ini", "mute", 299 );
    Config.Command_Event = ConfigGetInt    ( "commands.ini", "event", 299 );     //Event
    Config.Command_Npc = ConfigGetInt    ( "commands.ini", "npc", 299 );
    Config.Command_Pak = ConfigGetInt    ( "commands.ini", "pak", 299 );
    Config.Command_Pak2 = ConfigGetInt    ( "commands.ini", "pak2", 299 );
    Config.Command_Pakm = ConfigGetInt    ( "commands.ini", "pakm", 299 );
    Config.Command_Partylvl = ConfigGetInt      ( "commands.ini", "partylvl", 299);
    Config.Command_PlayerInfo = ConfigGetInt    ( "commands.ini", "playerinfo", 299 );
    Config.Command_Pdmg = ConfigGetInt    ( "commands.ini", "pdmg", 299 );
    Config.Command_Pvp = ConfigGetInt    ( "commands.ini", "pvp", 299 );
    Config.Command_Rate = ConfigGetInt    ( "commands.ini", "rate", 299 );
    Config.Command_Reborn = ConfigGetInt    ( "commands.ini", "reborn", 299 );  //Reborn by core
    Config.Command_Reload = ConfigGetInt    ( "commands.ini", "reload", 299 );
    Config.Command_ReloadQuest = ConfigGetInt    ( "commands.ini", "reloadquest", 299 );
    Config.Command_Rules = ConfigGetInt    ( "commands.ini", "rules", 99 );
    Config.Command_Save = ConfigGetInt    ( "commands.ini", "save", 299 );
    Config.Command_ServerInfo = ConfigGetInt    ( "commands.ini", "serverinfo", 299 );
    Config.Command_Set = ConfigGetInt    ( "commands.ini", "set", 299 );
    Config.Command_Settime = ConfigGetInt    ( "commands.ini", "settime", 299 );
    Config.Command_ShopType = ConfigGetInt    ( "commands.ini", "shoptype", 299 );
    Config.Command_BonusXp = ConfigGetInt    ( "commands.ini", "bonusxp", 299 );  //LMA: bonusxp
    Config.Command_Shutdown = ConfigGetInt    ( "commands.ini", "shutdown", 299 );
    Config.Command_SSpawn = ConfigGetInt    ( "commands.ini", "sspawn", 299 );
    Config.Command_Stat = ConfigGetInt    ( "commands.ini", "stat", 299 );
    Config.Command_Summon = ConfigGetInt    ( "commands.ini", "summon", 299 );
    Config.Command_TargetInfo = ConfigGetInt    ( "commands.ini", "targetinfo", 299 );
    Config.Command_Tele = ConfigGetInt    ( "commands.ini", "tele", 299 );
    Config.Command_TeleToMe = ConfigGetInt    ( "commands.ini", "teletome", 299 );
    Config.Command_Transx = ConfigGetInt    ( "commands.ini", "transx", 299 );
    Config.Command_grid = ConfigGetInt    ( "commands.ini", "grid", 299 );   //LMA: maps grids.  
    Config.Command_Who = ConfigGetInt    ( "commands.ini", "who", 299 );
    Config.Command_Who2 = ConfigGetInt    ( "commands.ini", "who2", 299 );
    Config.Command_Broadcast = ConfigGetInt    ( "commands.ini", "broadcast", 299 );
    Config.Command_GlobalTime  = ConfigGetInt    ( "commands.ini", "globaldelay", 30 );
    Config.Command_GlobalPrefix = ConfigGetString    ( "commands.ini", "globalprefix", "[Broadcast]" );
    Config.Command_MaxStats     = ConfigGetInt    ( "commands.ini", "maxstats", 299 );     //MaxStats

}
示例#28
0
// Load commands from commands.ini [by Paul_T]
void CWorldServer::LoadCommandLevels( void )
{
    Config.Command_Addquest = ConfigGetInt ( "commands.ini", "addquest", 299 );
    Config.Command_AllSkill = ConfigGetInt ( "commands.ini", "allskill", 299 );
    Config.Command_GMSkills = ConfigGetInt ( "commands.ini", "gmskills", 299 );
    Config.Command_Ani = ConfigGetInt    ( "commands.ini", "ani", 299 );
    Config.Command_Ann = ConfigGetInt    ( "commands.ini", "ann", 299 );
    Config.Command_AtkModif = ConfigGetInt    ( "commands.ini", "atkmodif", 299 );
    Config.Command_Ban = ConfigGetInt    ( "commands.ini", "ban", 299 );
    Config.Command_BonusXp = ConfigGetInt    ( "commands.ini", "bonusxp", 299 );  //LMA: bonusxp
    Config.Command_Broadcast = ConfigGetInt    ( "commands.ini", "broadcast", 299 );
    Config.Command_Buff = ConfigGetInt    ( "commands.ini", "buff", 299 );
    Config.Command_cart = ConfigGetInt    ( "commands.ini", "cart", 299 );  // all Cart Parts
    Config.Command_Cfmode = ConfigGetInt    ( "commands.ini", "cfmode", 299 );
    Config.Command_cg = ConfigGetInt    ( "commands.ini", "castlegear", 299 ); //get all CastleGear Parts
    Config.Command_Cha = ConfigGetInt    ( "commands.ini", "cha", 299 );
    Config.Command_ChangeFairyWait = ConfigGetInt    ( "commands.ini", "changefairywait", 299 );
    Config.Command_ChangeFairyStay = ConfigGetInt    ( "commands.ini", "changefairystay", 299 );
    Config.Command_ChangeFairyTestMode = ConfigGetInt    ( "commands.ini", "changefairytestmode", 299 );
    Config.Command_Class = ConfigGetInt    ( "commands.ini", "class", 299 );
    Config.Command_ConfigReset = ConfigGetInt    ( "commands.ini", "ConfigReset", 299 );
    Config.Command_Convert = ConfigGetInt    ( "commands.ini", "convert", 299 );
    Config.Command_Debuff = ConfigGetInt    ( "commands.ini", "debuff", 299 );
    Config.Command_DelSkills = ConfigGetInt ( "commands.ini", "delskills", 299 );
    Config.Command_DelSpawn = ConfigGetInt    ( "commands.ini", "delspawn", 299 );
    Config.Command_Dev = ConfigGetInt    ( "commands.ini", "dev", 299 );
    Config.Command_DQuest = ConfigGetInt    ( "commands.ini", "dquest", 299 );
    Config.Command_Drop = ConfigGetInt    ( "commands.ini", "drop", 299 );
    Config.Command_DSpawn = ConfigGetInt    ( "commands.ini", "dspawn", 299 );
    Config.Command_ESpawn = ConfigGetInt    ( "commands.ini", "espawn", 299 );
    Config.Command_Event = ConfigGetInt    ( "commands.ini", "event", 299 );     //Event
    Config.Command_EventIfo = ConfigGetInt    ( "commands.ini", "eventifo", 299 );     //LMA: Events for IFO Objects
    Config.Command_Exp = ConfigGetInt    ( "commands.ini", "exp", 299 );
    Config.Command_Face = ConfigGetInt    ( "commands.ini", "face", 299 );
    Config.Command_fskill = ConfigGetInt    ( "commands.ini", "fskill", 299 );     //LMA: Force a skill for a monster.
    Config.Command_Give2 = ConfigGetInt    ( "commands.ini", "give2", 299 );
    Config.Command_GiveClanRp = ConfigGetInt    ( "commands.ini", "giveclanrp", 299 );       //Reward points
    Config.Command_GiveClanp = ConfigGetInt    ( "commands.ini", "giveclanp", 299 );       //Clan points
    Config.Command_GiveFairy = ConfigGetInt    ( "commands.ini", "givefairy", 299 );
    Config.Command_GiveZuly = ConfigGetInt    ( "commands.ini", "givezuly", 299 );
    Config.Command_GlobalTime  = ConfigGetInt    ( "commands.ini", "globaldelay", 30 );
    Config.Command_GlobalPrefix = ConfigGetString    ( "commands.ini", "globalprefix", "[Broadcast]" );
    Config.Command_GmList = ConfigGetInt ( "commands.ini", "gmlist", 299 );
    Config.Command_Go = ConfigGetInt    ( "commands.ini", "go", 299 );
    Config.Command_Goto = ConfigGetInt    ( "commands.ini", "goto", 299 );
    Config.Command_GoToMap = ConfigGetInt    ( "commands.ini", "gotomap", 299 );
    Config.Command_grid = ConfigGetInt    ( "commands.ini", "grid", 299 );   //LMA: maps grids.
    Config.Command_Hair = ConfigGetInt    ( "commands.ini", "hair", 299 );
    Config.Command_Heal = ConfigGetInt    ( "commands.ini", "heal", 299 );
    Config.Command_Here = ConfigGetInt    ( "commands.ini", "here", 299 );
    Config.Command_Hide = ConfigGetInt    ( "commands.ini", "hide", 299 );
    Config.Command_HitModif = ConfigGetInt    ( "commands.ini", "hitmodif", 299 );
    Config.Command_HurtHim = ConfigGetInt    ( "commands.ini", "hurthim", 299 );
    Config.Command_Info = ConfigGetInt    ( "commands.ini", "info", 299 );
    Config.Command_IQuest = ConfigGetInt    ( "commands.ini", "iquest", 299 );
    Config.Command_Item = ConfigGetInt    ( "commands.ini", "item", 299 );
    Config.Command_ItemStat = ConfigGetInt    ( "commands.ini", "itemstat", 299 );
    Config.Command_Job = ConfigGetInt    ( "commands.ini", "job", 299 );
    Config.Command_Kick = ConfigGetInt    ( "commands.ini", "kick", 299 );
    Config.Command_KillInRange = ConfigGetInt    ( "commands.ini", "killinrange", 299 );
    Config.Command_Level = ConfigGetInt    ( "commands.ini", "level", 299 );
    Config.Command_LevelUp = ConfigGetInt    ( "commands.ini", "levelup", 299 );
    Config.Command_Listquest = ConfigGetInt ( "commands.ini", "listquest", 299 );
    Config.Command_Listqflag = ConfigGetInt ( "commands.ini", "listqflag", 299 );
    Config.Command_Listqvar = ConfigGetInt ( "commands.ini", "listqvar", 299 );
    Config.Command_ManageFairy = ConfigGetInt    ( "commands.ini", "managefairy", 299 );
    Config.Command_MaxStats     = ConfigGetInt    ( "commands.ini", "maxstats", 299 );     //MaxStats
    Config.Command_Mdmg = ConfigGetInt    ( "commands.ini", "mdmg", 299 );
    Config.Command_Mon = ConfigGetInt    ( "commands.ini", "mon", 299 );
    Config.Command_Mon2 = ConfigGetInt    ( "commands.ini", "mon2", 299 );
    Config.Command_Monster    = ConfigGetInt    ( "commands.ini", "monster", 299 );
    Config.Command_Move = ConfigGetInt    ( "commands.ini", "move", 299 );
    Config.Command_Moveto = ConfigGetInt    ( "commands.ini", "moveto", 299 );
    Config.Command_Mute = ConfigGetInt    ( "commands.ini", "mute", 299 );
    Config.Command_Npc = ConfigGetInt    ( "commands.ini", "npc", 299 );
    Config.Command_NpcObjVar = ConfigGetInt    ( "commands.ini", "npcobjvar", 299 );
    Config.Command_NpcSetObjVar = ConfigGetInt    ( "commands.ini", "npcsetobjvar", 299 );
    Config.Command_NpcLtb = ConfigGetInt    ( "commands.ini", "npcltb", 299 );
    Config.Command_Pak = ConfigGetInt    ( "commands.ini", "pak", 299 );
    Config.Command_Pak2 = ConfigGetInt    ( "commands.ini", "pak2", 299 );
    Config.Command_Pakm = ConfigGetInt    ( "commands.ini", "pakm", 299 );
    Config.Command_Partylvl = ConfigGetInt      ( "commands.ini", "partylvl", 299);
    Config.Command_Pdmg = ConfigGetInt    ( "commands.ini", "pdmg", 299 );
    Config.Command_PlayerInfo = ConfigGetInt    ( "commands.ini", "playerinfo", 299 );
    Config.Command_Pvp = ConfigGetInt    ( "commands.ini", "pvp", 299 );
    Config.Command_RaiseCG = ConfigGetInt    ( "commands.ini", "raisecg", 299 );
    Config.Command_Rate = ConfigGetInt    ( "commands.ini", "rate", 299 );
    Config.Command_Reborn = ConfigGetInt    ( "commands.ini", "reborn", 299 );  //Reborn by core
    Config.Command_Refine = ConfigGetInt    ( "commands.ini", "refine", 299 );  //Refine by PurpleYouko
    Config.Command_Reload = ConfigGetInt    ( "commands.ini", "reload", 299 );
    Config.Command_ReloadQuest = ConfigGetInt    ( "commands.ini", "reloadquest", 299 );
    Config.Command_Rules = ConfigGetInt    ( "commands.ini", "rules", 99 );
    Config.Command_Save = ConfigGetInt    ( "commands.ini", "save", 299 );
    Config.Command_ServerInfo = ConfigGetInt    ( "commands.ini", "serverinfo", 299 );
    Config.Command_Set = ConfigGetInt    ( "commands.ini", "set", 299 );
    Config.Command_Setqflag = ConfigGetInt ( "commands.ini", "setqflag", 299 );
    Config.Command_Setqvar = ConfigGetInt ( "commands.ini", "setqvar", 299 );
    Config.Command_Settime = ConfigGetInt    ( "commands.ini", "settime", 299 );
    Config.Command_SetUW = ConfigGetInt    ( "commands.ini", "setuw", 299 );
    Config.Command_SetUWnb = ConfigGetInt    ( "commands.ini", "setuwnb", 299 );
    Config.Command_ShopType = ConfigGetInt    ( "commands.ini", "shoptype", 299 );
    Config.Command_Shutdown = ConfigGetInt    ( "commands.ini", "shutdown", 299 );
    Config.Command_SpeedModif = ConfigGetInt    ( "commands.ini", "speedmodif", 299 );
    Config.Command_SSpawn = ConfigGetInt    ( "commands.ini", "sspawn", 299 );
    Config.Command_Stat = ConfigGetInt    ( "commands.ini", "stat", 299 );
    Config.Command_Summon = ConfigGetInt    ( "commands.ini", "summon", 299 );
    Config.Command_TargetInfo = ConfigGetInt    ( "commands.ini", "targetinfo", 299 );
    Config.Command_Tele = ConfigGetInt    ( "commands.ini", "tele", 299 );
    Config.Command_TeleToMe = ConfigGetInt    ( "commands.ini", "teletome", 299 );
    Config.Command_Transx = ConfigGetInt    ( "commands.ini", "transx", 299 );
    Config.Command_Union = ConfigGetInt    ( "commands.ini", "union", 299 );
    Config.Command_UnionPoints = ConfigGetInt    ( "commands.ini", "unionpoints", 299 );
    Config.Command_Who = ConfigGetInt    ( "commands.ini", "who", 299 );
    Config.Command_Who2 = ConfigGetInt    ( "commands.ini", "who2", 299 );
}
示例#29
0
static void HandleGameEvent(
	const GameEvent e,
	Camera *camera,
	PowerupSpawner *healthSpawner,
	CArray *ammoSpawners)
{
	switch (e.Type)
	{
	case GAME_EVENT_PLAYER_DATA:
		PlayerDataAddOrUpdate(e.u.PlayerData);
		break;
	case GAME_EVENT_TILE_SET:
		{
			Tile *t = MapGetTile(&gMap, Net2Vec2i(e.u.TileSet.Pos));
			t->flags = e.u.TileSet.Flags;
			t->pic = PicManagerGetNamedPic(
				&gPicManager, e.u.TileSet.PicName);
			t->picAlt = PicManagerGetNamedPic(
				&gPicManager, e.u.TileSet.PicAltName);
		}
		break;
	case GAME_EVENT_MAP_OBJECT_ADD:
		ObjAdd(e.u.MapObjectAdd);
		break;
	case GAME_EVENT_MAP_OBJECT_DAMAGE:
		DamageObject(e.u.MapObjectDamage);
		break;
	case GAME_EVENT_SCORE:
		{
			PlayerData *p = PlayerDataGetByUID(e.u.Score.PlayerUID);
			PlayerScore(p, e.u.Score.Score);
			HUDAddUpdate(
				&camera->HUD,
				NUMBER_UPDATE_SCORE, e.u.Score.PlayerUID, e.u.Score.Score);
		}
		break;
	case GAME_EVENT_SOUND_AT:
		if (!e.u.SoundAt.IsHit || ConfigGetBool(&gConfig, "Sound.Hits"))
		{
			SoundPlayAt(
				&gSoundDevice,
				StrSound(e.u.SoundAt.Sound), Net2Vec2i(e.u.SoundAt.Pos));
		}
		break;
	case GAME_EVENT_SCREEN_SHAKE:
		camera->shake = ScreenShakeAdd(
			camera->shake, e.u.ShakeAmount,
			ConfigGetInt(&gConfig, "Graphics.ShakeMultiplier"));
		break;
	case GAME_EVENT_SET_MESSAGE:
		HUDDisplayMessage(
			&camera->HUD, e.u.SetMessage.Message, e.u.SetMessage.Ticks);
		break;
	case GAME_EVENT_GAME_START:
		gMission.HasStarted = true;
		break;
	case GAME_EVENT_ACTOR_ADD:
		ActorAdd(e.u.ActorAdd);
		break;
	case GAME_EVENT_ACTOR_MOVE:
		ActorMove(e.u.ActorMove);
		break;
	case GAME_EVENT_ACTOR_STATE:
		{
			TActor *a = ActorGetByUID(e.u.ActorState.UID);
			if (!a->isInUse) break;
			ActorSetState(a, (ActorAnimation)e.u.ActorState.State);
		}
		break;
	case GAME_EVENT_ACTOR_DIR:
		{
			TActor *a = ActorGetByUID(e.u.ActorDir.UID);
			if (!a->isInUse) break;
			a->direction = (direction_e)e.u.ActorDir.Dir;
		}
		break;
	case GAME_EVENT_ACTOR_SLIDE:
		{
			TActor *a = ActorGetByUID(e.u.ActorSlide.UID);
			if (!a->isInUse) break;
			a->Vel = Net2Vec2i(e.u.ActorSlide.Vel);
			// Slide sound
			if (ConfigGetBool(&gConfig, "Sound.Footsteps"))
			{
				SoundPlayAt(
					&gSoundDevice,
					gSoundDevice.slideSound,
					Vec2iNew(a->tileItem.x, a->tileItem.y));
			}
		}
		break;
	case GAME_EVENT_ACTOR_IMPULSE:
		{
			TActor *a = ActorGetByUID(e.u.ActorImpulse.UID);
			if (!a->isInUse) break;
			a->Vel = Vec2iAdd(a->Vel, Net2Vec2i(e.u.ActorImpulse.Vel));
			const Vec2i pos = Net2Vec2i(e.u.ActorImpulse.Pos);
			if (!Vec2iIsZero(pos))
			{
				a->Pos = pos;
			}
		}
		break;
	case GAME_EVENT_ACTOR_SWITCH_GUN:
		ActorSwitchGun(e.u.ActorSwitchGun);
		break;
	case GAME_EVENT_ACTOR_PICKUP_ALL:
		{
			TActor *a = ActorGetByUID(e.u.ActorPickupAll.UID);
			if (!a->isInUse) break;
			a->PickupAll = e.u.ActorPickupAll.PickupAll;
		}
		break;
	case GAME_EVENT_ACTOR_REPLACE_GUN:
		ActorReplaceGun(e.u.ActorReplaceGun);
		break;
	case GAME_EVENT_ACTOR_HEAL:
		{
			TActor *a = ActorGetByUID(e.u.Heal.UID);
			if (!a->isInUse || a->dead) break;
			ActorHeal(a, e.u.Heal.Amount);
			// Sound of healing
			SoundPlayAt(
				&gSoundDevice,
				gSoundDevice.healthSound, Vec2iFull2Real(a->Pos));
			// Tell the spawner that we took a health so we can
			// spawn more (but only if we're the server)
			if (e.u.Heal.IsRandomSpawned && !gCampaign.IsClient)
			{
				PowerupSpawnerRemoveOne(healthSpawner);
			}
			if (e.u.Heal.PlayerUID >= 0)
			{
				HUDAddUpdate(
					&camera->HUD, NUMBER_UPDATE_HEALTH,
					e.u.Heal.PlayerUID, e.u.Heal.Amount);
			}
		}
		break;
	case GAME_EVENT_ACTOR_ADD_AMMO:
		{
			TActor *a = ActorGetByUID(e.u.AddAmmo.UID);
			if (!a->isInUse || a->dead) break;
			ActorAddAmmo(a, e.u.AddAmmo.AmmoId, e.u.AddAmmo.Amount);
			// Tell the spawner that we took ammo so we can
			// spawn more (but only if we're the server)
			if (e.u.AddAmmo.IsRandomSpawned && !gCampaign.IsClient)
			{
				PowerupSpawnerRemoveOne(
					CArrayGet(ammoSpawners, e.u.AddAmmo.AmmoId));
			}
			if (e.u.AddAmmo.PlayerUID >= 0)
			{
				HUDAddUpdate(
					&camera->HUD, NUMBER_UPDATE_AMMO,
					e.u.AddAmmo.PlayerUID, e.u.AddAmmo.Amount);
			}
		}
		break;
	case GAME_EVENT_ACTOR_USE_AMMO:
		{
			TActor *a = ActorGetByUID(e.u.UseAmmo.UID);
			if (!a->isInUse || a->dead) break;
			ActorAddAmmo(a, e.u.UseAmmo.AmmoId, -(int)e.u.UseAmmo.Amount);
			if (e.u.UseAmmo.PlayerUID >= 0)
			{
				HUDAddUpdate(
					&camera->HUD, NUMBER_UPDATE_AMMO,
					e.u.UseAmmo.PlayerUID, -(int)e.u.UseAmmo.Amount);
			}
		}
		break;
	case GAME_EVENT_ACTOR_DIE:
		{
			TActor *a = ActorGetByUID(e.u.ActorDie.UID);

			// Check if the player has lives to revive
			PlayerData *p = PlayerDataGetByUID(a->PlayerUID);
			if (p != NULL)
			{
				p->Lives--;
				CASSERT(p->Lives >= 0, "Player has died too many times");
				if (p->Lives > 0 && !gCampaign.IsClient)
				{
					// Find the closest player alive; try to spawn next to that position
					// if no other suitable position exists
					Vec2i defaultSpawnPosition = Vec2iZero();
					const TActor *closestActor = AIGetClosestPlayer(a->Pos);
					if (closestActor != NULL) defaultSpawnPosition = closestActor->Pos;
					PlacePlayer(&gMap, p, defaultSpawnPosition, false);
				}
			}

			ActorDestroy(a);
		}
		break;
	case GAME_EVENT_ACTOR_MELEE:
		{
			const TActor *a = ActorGetByUID(e.u.Melee.UID);
			if (!a->isInUse) break;
			const BulletClass *b = StrBulletClass(e.u.Melee.BulletClass);
			if ((HitType)e.u.Melee.HitType != HIT_NONE &&
				HasHitSound(b->Power, a->flags, a->PlayerUID,
				(TileItemKind)e.u.Melee.TargetKind, e.u.Melee.TargetUID,
				SPECIAL_NONE, false))
			{
				PlayHitSound(
					&b->HitSound, (HitType)e.u.Melee.HitType,
					Vec2iFull2Real(a->Pos));
			}
			if (!gCampaign.IsClient)
			{
				Damage(
					Vec2iZero(),
					b->Power,
					a->flags, a->PlayerUID, a->uid,
					(TileItemKind)e.u.Melee.TargetKind, e.u.Melee.TargetUID,
					SPECIAL_NONE);
			}
		}
		break;
	case GAME_EVENT_ADD_PICKUP:
		PickupAdd(e.u.AddPickup);
		// Play a spawn sound
		SoundPlayAt(
			&gSoundDevice,
			StrSound("spawn_item"), Net2Vec2i(e.u.AddPickup.Pos));
		break;
	case GAME_EVENT_REMOVE_PICKUP:
		PickupDestroy(e.u.RemovePickup.UID);
		if (e.u.RemovePickup.SpawnerUID >= 0)
		{
			TObject *o = ObjGetByUID(e.u.RemovePickup.SpawnerUID);
			o->counter = AMMO_SPAWNER_RESPAWN_TICKS;
		}
		break;
	case GAME_EVENT_BULLET_BOUNCE:
		{
			TMobileObject *o = MobObjGetByUID(e.u.BulletBounce.UID);
			if (o == NULL || !o->isInUse) break;
			const Vec2i pos = Net2Vec2i(e.u.BulletBounce.BouncePos);
			PlayHitSound(
				&o->bulletClass->HitSound, (HitType)e.u.BulletBounce.HitType,
				Vec2iFull2Real(pos));
			if (e.u.BulletBounce.Spark && o->bulletClass->Spark != NULL)
			{
				GameEvent s = GameEventNew(GAME_EVENT_ADD_PARTICLE);
				s.u.AddParticle.Class = o->bulletClass->Spark;
				s.u.AddParticle.FullPos = pos;
				s.u.AddParticle.Z = o->z;
				GameEventsEnqueue(&gGameEvents, s);
			}
			o->x = pos.x;
			o->y = pos.y;
			o->vel = Net2Vec2i(e.u.BulletBounce.BounceVel);
		}
		break;
	case GAME_EVENT_REMOVE_BULLET:
		{
			TMobileObject *o = MobObjGetByUID(e.u.RemoveBullet.UID);
			if (o == NULL || !o->isInUse) break;
			MobObjDestroy(o);
		}
		break;
	case GAME_EVENT_PARTICLE_REMOVE:
		ParticleDestroy(&gParticles, e.u.ParticleRemoveId);
		break;
	case GAME_EVENT_GUN_FIRE:
		{
			const GunDescription *g = StrGunDescription(e.u.GunFire.Gun);
			const Vec2i fullPos = Net2Vec2i(e.u.GunFire.MuzzleFullPos);

			// Add bullets
			if (g->Bullet && !gCampaign.IsClient)
			{
				// Find the starting angle of the spread (clockwise)
				// Keep in mind the fencepost problem, i.e. spread of 3 means a
				// total spread angle of 2x width
				const double spreadStartAngle =
					g->AngleOffset -
					(g->Spread.Count - 1) * g->Spread.Width / 2;
				for (int i = 0; i < g->Spread.Count; i++)
				{
					const double recoil =
						((double)rand() / RAND_MAX * g->Recoil) -
						g->Recoil / 2;
					const double finalAngle =
						e.u.GunFire.Angle + spreadStartAngle +
						i * g->Spread.Width + recoil;
					GameEvent ab = GameEventNew(GAME_EVENT_ADD_BULLET);
					ab.u.AddBullet.UID = MobObjsObjsGetNextUID();
					strcpy(ab.u.AddBullet.BulletClass, g->Bullet->Name);
					ab.u.AddBullet.MuzzlePos = Vec2i2Net(fullPos);
					ab.u.AddBullet.MuzzleHeight = e.u.GunFire.Z;
					ab.u.AddBullet.Angle = (float)finalAngle;
					ab.u.AddBullet.Elevation =
						RAND_INT(g->ElevationLow, g->ElevationHigh);
					ab.u.AddBullet.Flags = e.u.GunFire.Flags;
					ab.u.AddBullet.PlayerUID = e.u.GunFire.PlayerUID;
					ab.u.AddBullet.ActorUID = e.u.GunFire.UID;
					GameEventsEnqueue(&gGameEvents, ab);
				}
			}

			// Add muzzle flash
			if (GunHasMuzzle(g))
			{
				GameEvent ap = GameEventNew(GAME_EVENT_ADD_PARTICLE);
				ap.u.AddParticle.Class = g->MuzzleFlash;
				ap.u.AddParticle.FullPos = fullPos;
				ap.u.AddParticle.Z = e.u.GunFire.Z;
				ap.u.AddParticle.Angle = e.u.GunFire.Angle;
				GameEventsEnqueue(&gGameEvents, ap);
			}
			// Sound
			if (e.u.GunFire.Sound && g->Sound)
			{
				SoundPlayAt(&gSoundDevice, g->Sound, Vec2iFull2Real(fullPos));
			}
			// Screen shake
			if (g->ShakeAmount > 0)
			{
				GameEvent s = GameEventNew(GAME_EVENT_SCREEN_SHAKE);
				s.u.ShakeAmount = g->ShakeAmount;
				GameEventsEnqueue(&gGameEvents, s);
			}
			// Brass shells
			// If we have a reload lead, defer the creation of shells until then
			if (g->Brass && g->ReloadLead == 0)
			{
				const direction_e d = RadiansToDirection(e.u.GunFire.Angle);
				const Vec2i muzzleOffset = GunGetMuzzleOffset(g, d);
				GunAddBrass(g, d, Vec2iMinus(fullPos, muzzleOffset));
			}
		}
		break;
	case GAME_EVENT_GUN_RELOAD:
		{
			const GunDescription *g = StrGunDescription(e.u.GunReload.Gun);
			const Vec2i fullPos = Net2Vec2i(e.u.GunReload.FullPos);
			SoundPlayAtPlusDistance(
				&gSoundDevice,
				g->ReloadSound,
				Vec2iFull2Real(fullPos),
				RELOAD_DISTANCE_PLUS);
			// Brass shells
			if (g->Brass)
			{
				GunAddBrass(g, (direction_e)e.u.GunReload.Direction, fullPos);
			}
		}
		break;
	case GAME_EVENT_GUN_STATE:
		{
			const TActor *a = ActorGetByUID(e.u.GunState.ActorUID);
			if (!a->isInUse) break;
			WeaponSetState(ActorGetGun(a), (gunstate_e)e.u.GunState.State);
		}
		break;
	case GAME_EVENT_ADD_BULLET:
		BulletAdd(e.u.AddBullet);
		break;
	case GAME_EVENT_ADD_PARTICLE:
		ParticleAdd(&gParticles, e.u.AddParticle);
		break;
	case GAME_EVENT_ACTOR_HIT:
		{
			TActor *a = ActorGetByUID(e.u.ActorHit.UID);
			if (!a->isInUse) break;
			ActorTakeHit(a, e.u.ActorHit.Special);
			if (e.u.ActorHit.Power > 0)
			{
				DamageActor(
					a, e.u.ActorHit.Power, e.u.ActorHit.HitterPlayerUID);
				if (e.u.ActorHit.PlayerUID >= 0)
				{
					HUDAddUpdate(
						&camera->HUD, NUMBER_UPDATE_HEALTH,
						e.u.ActorHit.PlayerUID, -e.u.ActorHit.Power);
				}

				AddBloodSplatter(
					a->Pos, e.u.ActorHit.Power,
					Net2Vec2i(e.u.ActorHit.Vel));
			}
		}
		break;
	case GAME_EVENT_TRIGGER:
		{
			const Tile *t =
				MapGetTile(&gMap, Net2Vec2i(e.u.TriggerEvent.Tile));
			CA_FOREACH(Trigger *, tp, t->triggers)
				if ((*tp)->id == (int)e.u.TriggerEvent.ID)
				{
					TriggerActivate(*tp, &gMap.triggers);
					break;
				}
			CA_FOREACH_END()
		}
		break;
	case GAME_EVENT_EXPLORE_TILES:
		// Process runs of explored tiles
		for (int i = 0; i < (int)e.u.ExploreTiles.Runs_count; i++)
		{
			Vec2i tile = Net2Vec2i(e.u.ExploreTiles.Runs[i].Tile);
			for (int j = 0; j < e.u.ExploreTiles.Runs[i].Run; j++)
			{
				MapMarkAsVisited(&gMap, tile);
				tile.x++;
				if (tile.x == gMap.Size.x)
				{
					tile.x = 0;
					tile.y++;
				}
			}
		}
		break;
	case GAME_EVENT_RESCUE_CHARACTER:
		{
			TActor *a = ActorGetByUID(e.u.Rescue.UID);
			if (!a->isInUse) break;
			a->flags &= ~FLAGS_PRISONER;
			SoundPlayAt(
				&gSoundDevice, StrSound("rescue"), Vec2iFull2Real(a->Pos));
		}
		break;
	case GAME_EVENT_OBJECTIVE_UPDATE:
		{
			ObjectiveDef *o = CArrayGet(
				&gMission.Objectives, e.u.ObjectiveUpdate.ObjectiveId);
			o->done += e.u.ObjectiveUpdate.Count;
			// Display a text update effect for the objective
			HUDAddUpdate(
				&camera->HUD, NUMBER_UPDATE_OBJECTIVE,
				e.u.ObjectiveUpdate.ObjectiveId, e.u.ObjectiveUpdate.Count);
			MissionSetMessageIfComplete(&gMission);
		}
		break;
	case GAME_EVENT_ADD_KEYS:
		gMission.KeyFlags |= e.u.AddKeys.KeyFlags;
		SoundPlayAt(
			&gSoundDevice, gSoundDevice.keySound, Net2Vec2i(e.u.AddKeys.Pos));
		// Clear cache since we may now have new paths
		PathCacheClear(&gPathCache);
		break;
	case GAME_EVENT_MISSION_COMPLETE:
		if (e.u.MissionComplete.ShowMsg)
		{
			HUDDisplayMessage(&camera->HUD, "Mission complete", -1);
		}
		camera->HUD.showExit = true;
		MapShowExitArea(&gMap);
		break;
	case GAME_EVENT_MISSION_INCOMPLETE:
		gMission.state = MISSION_STATE_PLAY;
		break;
	case GAME_EVENT_MISSION_PICKUP:
		gMission.state = MISSION_STATE_PICKUP;
		gMission.pickupTime = gMission.time;
		SoundPlay(&gSoundDevice, StrSound("whistle"));
		break;
	case GAME_EVENT_MISSION_END:
		gMission.isDone = true;
		break;
	default:
		assert(0 && "unknown game event");
		break;
	}
}