char *GrafxGetModeStr(void) { static char buf[16]; sprintf(buf, "%dx%d", ConfigGetInt(&gConfig, "Graphics.ResolutionWidth"), ConfigGetInt(&gConfig, "Graphics.ResolutionHeight")); return buf; }
void GraphicsConfigSetFromConfig(GraphicsConfig *c) { GraphicsConfigSet( c, Vec2iNew( ConfigGetInt(&gConfig, "Graphics.ResolutionWidth"), ConfigGetInt(&gConfig, "Graphics.ResolutionHeight")), ConfigGetBool(&gConfig, "Graphics.Fullscreen"), ConfigGetInt(&gConfig, "Graphics.ScaleFactor")); }
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")); }
/*++ 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); }
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); } }
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); } }
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; }
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); } } } } }
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()); } } }
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); }
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; }
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; }
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 }
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 }
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; }
void CampaignInit(CampaignOptions *campaign) { memset(campaign, 0, sizeof *campaign); CampaignSettingInit(&campaign->Setting); campaign->seed = ConfigGetInt(&gConfig, "Game.RandomSeed"); }
// 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; }
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; }
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); }
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; } } } }
// 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 ); }
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");
// 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(); }
// 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(); }
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++; } }
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; }
// 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 }
// 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 ); }
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; } }