QUAT UnitList::getTrackableUnifiedHandleRotation(UnifiedHandle unifiedHandle) const { UnitList *thism = const_cast<UnitList *>(this); Unit *u = thism->getUnitById(unifiedHandleToUnitId(unifiedHandle)); assert(u != NULL); VC3 rot = u->getRotation(); QUAT ret = QUAT(UNIT_ANGLE_TO_RAD(rot.x), UNIT_ANGLE_TO_RAD(rot.y), UNIT_ANGLE_TO_RAD(rot.z)); return ret; }
void PositionScripting::process(util::ScriptProcess *sp, int command, int intData, char *stringData, ScriptLastValueType *lastValue, GameScriptData *gsd, Game *game) { switch(command) { case GS_CMD_SETPOSITION: { VC3 tmp(0,0,0); if (gs_coordinate_param(game->gameMap, stringData, &tmp)) { float x = tmp.x; float y = tmp.z; game->gameMap->keepWellInScaledBoundaries(&x, &y); gsd->position = VC3( x, game->gameMap->getScaledHeightAt(x,y), y); } else { sp->error("PositionScripting::process - Missing or bad setPosition parameter."); } } break; case GS_CMD_POSITIONRANDOMOFFSET: if (intData > 0) { int o1 = (game->gameRandom->nextInt() % (intData * 20 + 10)) - intData*10; int o2 = (game->gameRandom->nextInt() % (intData * 20 + 10)) - intData*10; int o3 = (game->gameRandom->nextInt() % (intData * 20 + 10)) - intData*10; gsd->position.x += (float)o1 * 0.1f; gsd->position.y += (float)o2 * 0.1f; gsd->position.z += (float)o3 * 0.1f; } else { sp->warning("PositionScripting::process - positionRandomOffset with zero parameter."); lastValue = 0; } break; case GS_CMD_MOVEPOSITIONZ: gsd->position.z += (float)intData / 100.0f; break; case GS_CMD_MOVEPOSITIONX: gsd->position.x += (float)intData / 100.0f; break; case GS_CMD_MOVEPOSITIONZFLOAT: { float floatData = *((float *)(&intData)); gsd->position.z += floatData; } break; case GS_CMD_MOVEPOSITIONXFLOAT: { float floatData = *((float *)(&intData)); gsd->position.x += floatData; } break; case GS_CMD_GETPOSITIONX: *lastValue = (int)gsd->position.x; break; case GS_CMD_GETPOSITIONZ: *lastValue = (int)gsd->position.z; break; case GS_CMD_GETPOSITIONHEIGHT: *lastValue = (int)gsd->position.y; break; case GS_CMD_GETACCURATEPOSITIONX: *lastValue = (int)(gsd->position.x * 1000.0f); break; case GS_CMD_GETACCURATEPOSITIONZ: *lastValue = (int)(gsd->position.z * 1000.0f); break; case GS_CMD_SETPOSITIONHEIGHT: if (stringData != NULL) { gsd->position.y = (float)atof(stringData); } else { sp->error("PositionScripting::process - Missing setPositionHeight parameter."); } break; case GS_CMD_SETPOSITIONHEIGHTONGROUND: { float x = gsd->position.x; float y = gsd->position.z; game->gameMap->keepWellInScaledBoundaries(&x, &y); gsd->position = VC3( x, game->gameMap->getScaledHeightAt(x,y), y); } break; case GS_CMD_POSITIONACCURATERANDOMOFFSET: if (intData > 0) { // intData values in cm int o1 = (game->gameRandom->nextInt() % (intData * 20 + 10)) - intData*10; int o2 = (game->gameRandom->nextInt() % (intData * 20 + 10)) - intData*10; int o3 = (game->gameRandom->nextInt() % (intData * 20 + 10)) - intData*10; gsd->position.x += (float)o1 * 0.1f * 0.01f; gsd->position.y += (float)o2 * 0.1f * 0.01f; gsd->position.z += (float)o3 * 0.1f * 0.01f; } else { sp->warning("PositionScripting::process - positionRandomOffset with zero parameter."); lastValue = 0; } break; case GS_CMD_MOVEPOSITIONHEIGHT: gsd->position.y += (float)intData / 100.0f; break; case GS_CMD_SETSECONDARYPOSITION: gsd->secondaryPosition = gsd->position; break; case GS_CMD_GETSECONDARYPOSITION: gsd->position = gsd->secondaryPosition; break; case GS_CMD_SETPOSITIONX: gsd->position.x = (float)*lastValue; break; case GS_CMD_SETPOSITIONZ: gsd->position.z = (float)*lastValue; break; case GS_CMD_SETACCURATEPOSITIONX: gsd->position.x = (float)*lastValue / 1000.0f; break; case GS_CMD_SETACCURATEPOSITIONZ: gsd->position.z = (float)*lastValue / 1000.0f; break; case GS_CMD_setAccuratePositionHeight: gsd->position.y = (float)*lastValue / 1000.0f; break; case GS_CMD_getAccuratePositionHeight: *lastValue = (int)(gsd->position.y * 1000.0f); break; case GS_CMD_PUSHGLOBALTEMPPOSITION: if (gs_global_temp_position_used) { sp->warning("PositionScripting::process - pushGlobalTempPosition, stack full."); } gs_global_temp_position_used = true; gs_global_temp_position = gsd->position; break; case GS_CMD_POPGLOBALTEMPPOSITION: if (!gs_global_temp_position_used) { sp->warning("PositionScripting::process - popGlobalTempPosition, stack empty."); } gsd->position = gs_global_temp_position; gs_global_temp_position_used = false; gs_global_temp_position = VC3(0,0,0); break; case GS_CMD_MOVEPOSITIONTOANGLEVALUE: { float angle = (float)(*lastValue); if (angle < 0) angle += 360; if (angle >= 360) angle -= 360; float amount= (float)intData / 100.0f; gsd->position.x += -amount * sinf(UNIT_ANGLE_TO_RAD(angle)); gsd->position.z += -amount * cosf(UNIT_ANGLE_TO_RAD(angle)); } break; case GS_CMD_ISPOSITIONINSIDEBUILDING: { VC3 pos = gsd->position; int x = game->gameMap->scaledToPathfindX(pos.x); int y = game->gameMap->scaledToPathfindY(pos.z); if (game->gameMap->isWellInScaledBoundaries(pos.x, pos.z)) { if (game->gameMap->getAreaMap()->isAreaAnyValue(x, y, AREAMASK_INBUILDING)) *lastValue = 1; else *lastValue = 0; } else { *lastValue = 0; } } break; case GS_CMD_isPositionBlockedByUnmoving: { VC3 pos = gsd->position; int x = game->gameMap->scaledToPathfindX(pos.x); int y = game->gameMap->scaledToPathfindY(pos.z); if (game->gameMap->isWellInScaledBoundaries(pos.x, pos.z)) { if (game->gameMap->getObstacleHeight(x, y) > 0 && !game->gameMap->isMovingObstacle(x, y)) *lastValue = 1; else *lastValue = 0; } else { *lastValue = 0; } } break; case GS_CMD_isPositionBlockedByUnmovingOrDoor: { VC3 pos = gsd->position; int x = game->gameMap->scaledToPathfindX(pos.x); int y = game->gameMap->scaledToPathfindY(pos.z); if (game->gameMap->isWellInScaledBoundaries(pos.x, pos.z)) { // HACK: rounded moving obstacles are actually doors if (game->gameMap->getObstacleHeight(x, y) > 0 && (!game->gameMap->isMovingObstacle(x, y) || game->gameMap->isRoundedObstacle(x, y))) *lastValue = 1; else *lastValue = 0; } else { *lastValue = 0; } } break; case GS_CMD_isPositionBlockedByMoving: { VC3 pos = gsd->position; int x = game->gameMap->scaledToPathfindX(pos.x); int y = game->gameMap->scaledToPathfindY(pos.z); if (game->gameMap->isWellInScaledBoundaries(pos.x, pos.z)) { if (game->gameMap->getObstacleHeight(x, y) > 0 && game->gameMap->isMovingObstacle(x, y)) *lastValue = 1; else *lastValue = 0; } else { *lastValue = 0; } } break; case GS_CMD_setPositionVariable: if (stringData != NULL) { bool success = sp->getScript()->setGlobalPositionVariableValue(stringData, gsd->position.x, gsd->position.y, gsd->position.z); if (!success) { sp->error("PositionScripting::process - setPositionVariable, failed to set position variable value (variable does not exist or type mismatch)."); sp->debug(stringData); } } else { sp->error("PositionScripting::process - setPositionVariable parameter missing, position variable name expected."); } break; case GS_CMD_getPositionVariable: if (stringData != NULL) { float tmpx, tmpy, tmpz; bool success = sp->getScript()->getGlobalPositionVariableValue(stringData, &tmpx, &tmpy, &tmpz); if (success) { gsd->position = VC3(tmpx, tmpy, tmpz); } else { sp->error("PositionScripting::process - getPositionVariable, failed to get position variable value (variable does not exist or type mismatch)."); sp->debug(stringData); } } else { sp->error("PositionScripting::process - getPositionVariable parameter missing, position variable name expected."); } break; case GS_CMD_addPositionVariableToPosition: if (stringData != NULL) { float tmpx, tmpy, tmpz; bool success = sp->getScript()->getGlobalPositionVariableValue(stringData, &tmpx, &tmpy, &tmpz); if (success) { gsd->position += VC3(tmpx, tmpy, tmpz); } else { sp->error("PositionScripting::process - addPositionVariableToPosition, failed to get position variable value (variable does not exist or type mismatch)."); sp->debug(stringData); } } else { sp->error("PositionScripting::process - addPositionVariableToPosition parameter missing, position variable name expected."); } break; case GS_CMD_setPositionKeepingHeight: { VC3 tmp(0,0,0); if (gs_coordinate_param(game->gameMap, stringData, &tmp)) { gsd->position.x = tmp.x; gsd->position.y = tmp.y; } else { sp->error("PositionScripting::process - Missing or bad setPositionKeepingHeight parameter."); } } break; case GS_CMD_setPositionXToFloat: { float floatData = *((float *)&intData); gsd->position.x = floatData; } break; case GS_CMD_setPositionZToFloat: { float floatData = *((float *)&intData); gsd->position.z = floatData; } break; case GS_CMD_rayTraceToSecondaryPosition: { VC3 middle_pos = (gsd->secondaryPosition + gsd->position) * 0.5f; VC3 dir = gsd->secondaryPosition - gsd->position; float length = dir.GetLength(); dir *= 1.0f / length; bool no_units = stringData && strstr(stringData, "no_units"); // disable collision for units if(no_units) { IUnitListIterator *iter = game->units->getNearbyAllUnits(middle_pos, length * length); while (iter->iterateAvailable()) { Unit *u = iter->iterateNext(); if(u && u->getVisualObject()) { u->getVisualObject()->setCollidable(false); } } delete iter; } // raycast *lastValue = 0; if(game && game->getGameScene()) { GameCollisionInfo cinfo; game->getGameScene()->rayTrace(gsd->position, dir, length, cinfo, true, false); if(cinfo.hit) { gsd->position = cinfo.position; *lastValue = 1; } } // re-enable collision for units if(no_units) { IUnitListIterator *iter = game->units->getNearbyAllUnits(middle_pos, length * length); while (iter->iterateAvailable()) { Unit *u = iter->iterateNext(); if(u && u->getVisualObject()) { u->getVisualObject()->setCollidable(true); } } delete iter; } } break; default: sp->error("PositionScripting::process - Unknown command."); assert(0); } }
void CameraScripting::process(util::ScriptProcess *sp, int command, floatint intFloat, char *stringData, ScriptLastValueType *lastValue, GameScriptData *gsd, Game *game) { int intData = intFloat.i; switch(command) { case GS_CMD_CAMERAPOSITION: // TODO: proper handling of players in netgame gsd->position = game->gameUI->getGameCamera()->getPosition(); #ifdef LEGACY_FILES // ok #else sp->warning("CameraScripting::process - cameraPosition deprecated, use actualCameraPosition instead."); #endif break; case GS_CMD_LISTENERPOSITION: // TODO: proper handling of players in netgame // TODO: real listener position, this is just an approximation... // (that is, using camera position as the camera position for now) //gsd->position = game->gameUI->getGameCamera()->getPosition(); gsd->position = game->gameUI->getListenerPosition(); break; case GS_CMD_SETCAMERAPOSITIONNEAR: // TODO: proper handling of players in netgame game->gameUI->getGameCamera()->setPositionNear(gsd->position.x, gsd->position.z); break; case GS_CMD_SETCAMERAPOSITION: { // new: global offsetting via 2 pivots and rotation around the nwe "pivot". VC3 pos = gsd->position; pos -= Ani::getGlobalOffsetSource(); float angle = Ani::getGlobalRotation(); float tmpX = pos.x; pos.x = pos.x * cosf(UNIT_ANGLE_TO_RAD(angle)) + pos.z * sinf(UNIT_ANGLE_TO_RAD(angle)); pos.z = pos.z * cosf(UNIT_ANGLE_TO_RAD(angle)) - tmpX * sinf(UNIT_ANGLE_TO_RAD(angle)); pos += Ani::getGlobalOffsetTarget(); game->gameUI->getGameCamera()->setPosition(pos); game->gameUI->getGameCamera()->doMovement(1); } break; case GS_CMD_rotateCameraAroundPosition: game->gameUI->getGameCamera()->rotateAroundPosition(gsd->position, *lastValue); game->gameUI->getGameCamera()->doMovement(1); break; case GS_CMD_SETCAMERAANGLE: // TODO: proper handling of players in netgame if (intData >= 0 || intData < 360) { float angle = (float)intData; angle += Ani::getGlobalRotation(); if (angle < 0) angle += 360.0f; if (angle > 360.0f) angle -= 360.0f; game->gameUI->getGameCamera()->setAngleY(angle); } else { sp->error("GameScripting::process - setCameraAngle parameter bad."); } game->gameUI->getGameCamera()->doMovement(1); break; case GS_CMD_SETCAMERAANGLEFLOAT: { float floatData = intFloat.f; if (floatData >= 0.0f || floatData < 360.0f) { floatData -= Ani::getGlobalRotation(); if (floatData < 0) floatData += 360.0f; if (floatData > 360.0f) floatData -= 360.0f; game->gameUI->getGameCamera()->setAngleY(floatData); } else { sp->error("GameScripting::process - setCameraAngleFloat parameter bad."); } game->gameUI->getGameCamera()->doMovement(1); } break; case GS_CMD_SETCAMERAANGLETOVALUE: game->gameUI->getGameCamera()->setAngleY((float)(90 - *lastValue)); game->gameUI->getGameCamera()->doMovement(1); break; case GS_CMD_GETCAMERAANGLE: { *lastValue = (int)game->gameUI->getGameCamera()->getAngleY(); *lastValue = 270 - *lastValue; if (*lastValue < 0) *lastValue += 360; } break; case GS_CMD_GETCAMERABETAANGLE: { *lastValue = (int)game->gameUI->getGameCamera()->getBetaAngle(); } break; case GS_CMD_SETCAMERABETAANGLE: // TODO: proper handling of players in netgame if (intData >= -180 || intData < 180) { game->gameUI->getGameCamera()->setBetaAngle((float)intData); } else { sp->error("GameScripting::process - setCameraBetaAngle parameter bad."); } game->gameUI->getGameCamera()->doMovement(1); break; case GS_CMD_SETCAMERABETAANGLEFLOAT: { float floatData = intFloat.f; if (floatData >= -180 || floatData < 180) { game->gameUI->getGameCamera()->setBetaAngle(floatData); } else { sp->error("GameScripting::process - setCameraBetaAngleFloat parameter bad."); } game->gameUI->getGameCamera()->doMovement(1); } break; case GS_CMD_SETCAMERAZOOM: // TODO: proper handling of players in netgame game->gameUI->getGameCamera()->setZoom((float)intData); game->gameUI->getGameCamera()->doMovement(1); break; case GS_CMD_SETCAMERAFLOATZOOM: if (stringData != NULL) { game->gameUI->getGameCamera()->setZoom((float)atof(stringData)); game->gameUI->getGameCamera()->doMovement(1); } else { sp->error("GameScripting::process - setCameraFloatZoom parameter missing."); } break; case GS_CMD_SELECTCAMERA: if (stringData != NULL) { // oh yeah! copy & paste programming ahead... if (strncmp(stringData, "cinematic1,", 11) == 0) { GameCamera *curcam = game->gameUI->getGameCamera(); game->gameUI->selectCamera(GAMEUI_CAMERA_CINEMATIC1); int itime = str2int(&stringData[11]); if (itime != 0) game->gameUI->getGameCamera()->interpolateFrom(curcam, (float)itime); else game->gameUI->getGameCamera()->interpolateFrom(game->gameUI->getGameCamera(), 0); game->gameUI->getGameCamera()->doMovement(1); break; } if (strncmp(stringData, "cinematic2,", 11) == 0) { GameCamera *curcam = game->gameUI->getGameCamera(); game->gameUI->selectCamera(GAMEUI_CAMERA_CINEMATIC2); int itime = str2int(&stringData[11]); if (itime != 0) game->gameUI->getGameCamera()->interpolateFrom(curcam, (float)itime); else game->gameUI->getGameCamera()->interpolateFrom(game->gameUI->getGameCamera(), 0); game->gameUI->getGameCamera()->doMovement(1); break; } if (strncmp(stringData, "normal,", 7) == 0) { GameCamera *curcam = game->gameUI->getGameCamera(); game->gameUI->selectCamera(GAMEUI_CAMERA_NORMAL); int itime = str2int(&stringData[7]); if (itime != 0) game->gameUI->getGameCamera()->interpolateFrom(curcam, (float)itime); else game->gameUI->getGameCamera()->interpolateFrom(game->gameUI->getGameCamera(), 0); game->gameUI->getGameCamera()->doMovement(1); break; } if (strncmp(stringData, "tactical,", 9) == 0) { GameCamera *curcam = game->gameUI->getGameCamera(); game->gameUI->selectCamera(GAMEUI_CAMERA_TACTICAL); int itime = str2int(&stringData[9]); if (itime != 0) game->gameUI->getGameCamera()->interpolateFrom(curcam, (float)itime); else game->gameUI->getGameCamera()->interpolateFrom(game->gameUI->getGameCamera(), 0); game->gameUI->getGameCamera()->doMovement(1); break; } sp->error("GameScripting::process - selectCamera parameter bad."); } else { sp->error("GameScripting::process - selectCamera parameter expected."); } break; case GS_CMD_SETCAMERAMOVEMENTON: // TODO: proper handling of players in netgame if (stringData != NULL) { GameCamera::CAMERA_MOVE moveNum = GameCamera::getCameraMoveByName(stringData); if (moveNum != GameCamera::CAMERA_MOVE_INVALID) { game->gameUI->getGameCamera()->setMovement(moveNum, true); } else { sp->error("GameScripting::process - setCameraMovementOn parameter invalid."); } } else { sp->error("GameScripting::process - setCameraMovementOn parameter missing."); } break; case GS_CMD_SETCAMERAMOVEMENTOFF: // TODO: proper handling of players in netgame if (stringData != NULL) { GameCamera::CAMERA_MOVE moveNum = GameCamera::getCameraMoveByName(stringData); if (moveNum != GameCamera::CAMERA_MOVE_INVALID) { game->gameUI->getGameCamera()->setMovement(moveNum, false); } else { sp->error("GameScripting::process - setCameraMovementOff parameter invalid."); } } else { sp->error("GameScripting::process - setCameraMovementOff parameter missing."); } break; case GS_CMD_SETCAMERAMODE: // TODO: proper handling of players in netgame if (stringData != NULL) { GameCamera::CAMERA_MODE modeNum = GameCamera::getCameraModeByName(stringData); if (modeNum != GameCamera::CAMERA_MODE_INVALID) { game->gameUI->getGameCamera()->setMode(modeNum); game->gameUI->getGameCamera()->doMovement(1); } else { sp->error("GameScripting::process - setCameraMode parameter invalid."); } } else { sp->error("GameScripting::process - setCameraMode parameter missing."); } break; case GS_CMD_SETCAMERATIMEFACTOR: if (stringData != NULL) { float timeFactor = (float)atof(stringData); if (timeFactor < 0.1f) timeFactor = 0.1f; if (timeFactor > 10.0f) timeFactor = 10.0f; game->gameUI->setCameraTimeFactor(timeFactor); } else { sp->error("GameScripting::process - setCameraTimeFactor parameter missing."); } break; case GS_CMD_ISCAMERAZOOMLESSTHAN: if (game->gameUI->getGameCamera()->getZoom() < (float)intData) { *lastValue = 1; } else { *lastValue = 0; } break; case GS_CMD_ISCAMERAZOOMGREATERTHAN: if (game->gameUI->getGameCamera()->getZoom() > (float)intData) { *lastValue = 1; } else { *lastValue = 0; } break; case GS_CMD_SETCAMERAFOV: game->gameUI->getGameCamera()->setFOV((float)intData); break; case GS_CMD_setCameraFOVFloat: { float floatData = intFloat.f; game->gameUI->getGameCamera()->setFOV(floatData); } break; case GS_CMD_COPYCAMERATO: if (stringData != NULL) { int curnum = game->gameUI->getCameraNumber(); GameCamera *curcam = game->gameUI->getGameCamera(); bool paramok = false; if (strcmp(stringData, "cinematic1") == 0) { game->gameUI->selectCamera(GAMEUI_CAMERA_CINEMATIC1); paramok = true; } if (strcmp(stringData, "cinematic2") == 0) { game->gameUI->selectCamera(GAMEUI_CAMERA_CINEMATIC2); paramok = true; } if (strcmp(stringData, "normal") == 0) { game->gameUI->selectCamera(GAMEUI_CAMERA_NORMAL); paramok = true; } if (strcmp(stringData, "tactical") == 0) { game->gameUI->selectCamera(GAMEUI_CAMERA_TACTICAL); paramok = true; } game->gameUI->getGameCamera()->copyFrom(curcam); game->gameUI->selectCamera(curnum); game->gameUI->getGameCamera()->doMovement(1); if (!paramok) { sp->error("GameScripting::process - selectCamera parameter bad."); } } else { sp->error("GameScripting::process - selectCamera parameter expected."); } break; case GS_CMD_setMapView: { bool showMap = stringData != NULL ? true : false; if(strcmp("stringData", "0") == 0) showMap = false; IStorm3D *storm = game->getGameUI()->getStorm3D(); int dummy1 = 0, dummy2 = 0; if(showMap) { game->gameScripting->runSingleSimpleStringCommand( "hideGUI", "", &dummy1, &dummy2 ); game->gameScripting->runSingleSimpleStringCommand( "hideAllUnits", "", &dummy1, &dummy2 ); game->getEnvironmentalEffectManager()->enableSunlight(); game->getEnvironmentalEffectManager()->setSunlightDirection ( VC3( 1,-1, 1) ); game->getEnvironmentalEffectManager()->setSunlightColor ( COL(1,1,1) ); } else { game->gameScripting->runSingleSimpleStringCommand( "showAllUnits", "", &dummy1, &dummy2 ); game->gameScripting->runSingleSimpleStringCommand( "showGUI", "", &dummy1, &dummy2 ); game->getEnvironmentalEffectManager()->disableSunlight(); } if(showMap) { float scrAspect; if(storm->getRenderTarget(0)) scrAspect = (float)storm->getRenderTarget(0)->getWidth() / storm->getRenderTarget(0)->getHeight(); else scrAspect = (float)storm->GetScreenSize().width / storm->GetScreenSize().height; int areaX = -1, areaY = -1; // if stringData is in form NxN, where N is a number... if( strlen(stringData) == 3 && ( stringData[0] >='1' && stringData[0] <='9' ) && ( stringData[1] == 'x' ) && ( stringData[2] >='1' && stringData[2] <='9' ) ) { areaX = stringData[0] - '1'; areaY = stringData[2] - '1'; } game->gameUI->getGameCamera()->setForceMapView(true, areaX, areaY, 1024, 1024, scrAspect ); } else game->gameUI->getGameCamera()->setForceMapView(false); } break; case GS_CMD_ROTATECAMERATOWARDUNIT: if (gsd->unit != NULL) { VC3 upos = gsd->unit->getPosition(); VC3 campos = game->gameUI->getGameCamera()->getPosition(); VC3 midpos(0,0,0); VC3 rotation(0,0,0); float scale; util::ObjectStretchingCalculator::calculateStretchValues( campos, upos, &midpos, &rotation, &scale); rotation.y = 270 - rotation.y; if (rotation.y < 0) rotation.y += 360; game->gameUI->getGameCamera()->setAngleY(rotation.y); game->gameUI->getGameCamera()->setBetaAngle(-rotation.x); game->gameUI->getGameCamera()->doMovement(1); } else { sp->warning("GameScripting::process - Attempt to rotateCameraTowardUnit for null unit."); } break; case GS_CMD_SETCAMERAHEIGHT: // TODO: proper handling of players in netgame game->gameUI->getGameCamera()->setHeight((float)intData); game->gameUI->getGameCamera()->doMovement(1); break; case GS_CMD_SHAKECAMERANEARPOSITIONSHORT: game->gameUI->getGameCamera()->setShakeEffect(intData, 500, gsd->position); break; case GS_CMD_SHAKECAMERANEARPOSITIONMEDIUM: game->gameUI->getGameCamera()->setShakeEffect(intData, 2500, gsd->position); break; case GS_CMD_SHAKECAMERANEARPOSITIONLONG: game->gameUI->getGameCamera()->setShakeEffect(intData, 8000, gsd->position); break; case GS_CMD_SETCAMERAINTERPOLATIONTYPE: if (stringData != NULL) { if (strcmp(stringData, "sinwave") == 0) { game->gameUI->getGameCamera()->setSmoothCameraInterpolation(true); } else if (strcmp(stringData, "linear") == 0) { game->gameUI->getGameCamera()->setSmoothCameraInterpolation(false); } else { sp->error("GameScripting::process - setCameraInterpolationType parameter bad."); } } else { // TODO: error } break; case GS_CMD_SETCAMERARANGE: if (intData > 0) { game->gameUI->setCameraRange((float)intData); } else { sp->error("GameScripting::process - setCameraRange parameter out of range (positive range value expected)."); } break; case GS_CMD_GETCAMERARANGE: *lastValue = (int)game->gameUI->getCameraRange(); break; case GS_CMD_RESTORECAMERARANGE: game->gameUI->restoreCameraRange(); break; case GS_CMD_SETCAMERATARGETDISTANCE: if (game->inCombat) { game->gameUI->getGameCamera()->setTargetDistance((float)intData); } break; case GS_CMD_RESTORECAMERATARGETDISTANCE: if (game->inCombat) { game->gameUI->getGameCamera()->restoreDefaultTargetDistance(); } break; case GS_CMD_setCameraAutozoomIndoor: if (game->inCombat) { float floatData = intFloat.f; ui::CameraAutozoomer::setAreaZoom(ui::CameraAutozoomer::CAMERA_AUTOZOOMER_AREA_INDOOR, floatData); } break; case GS_CMD_setCameraAutozoomOutdoor: if (game->inCombat) { float floatData = intFloat.f; ui::CameraAutozoomer::setAreaZoom(ui::CameraAutozoomer::CAMERA_AUTOZOOMER_AREA_OUTDOOR, floatData); } break; case GS_CMD_saveCameraAutozoom: if (game->inCombat) { ui::CameraAutozoomer::saveCheckpointState(); } break; case GS_CMD_loadCameraAutozoom: if (game->inCombat) { ui::CameraAutozoomer::loadCheckpointState(); } break; case GS_CMD_setCameraUpVector: if (stringData != NULL) { VC3 upvec = VC3(0,0,0); if (gs_tricoord_param(stringData, &upvec)) { if (!(upvec.GetSquareLength() > 0.99f * 0.99f && upvec.GetSquareLength() < 1.01f * 1.01f)) { sp->warning("CameraScripting::process - setCameraUpVector parameter is not a normalized vector (will be normalized)."); } if (!(upvec.GetSquareLength() > 0.001f * 0.001f)) { sp->warning("CameraScripting::process - setCameraUpVector parameter is a zero length or invalid vector (falling back to default)."); upvec = VC3(0,1,0); } upvec.Normalize(); game->gameUI->getGameCamera()->setUpVector(upvec); } else { sp->error("CameraScripting::process - setCameraUpVector parameter invalid (expected vector in format x,y,z)."); } } else { sp->error("CameraScripting::process - setCameraUpVector parameter missing (expected vector in format x,y,z)."); } break; case GS_CMD_setCameraNearClipValue: { float floatData = intFloat.f; if( game && game->gameScene && game->gameScene->getStormScene() && game->gameScene->getStormScene()->GetCamera() ) game->gameScene->getStormScene()->GetCamera()->SetZNear( floatData ); } break; case GS_CMD_setCameraNearClipDefault: if( game && game->gameScene && game->gameScene->getStormScene() && game->gameScene->getStormScene()->GetCamera() ) game->gameScene->getStormScene()->GetCamera()->SetZNearDefault(); break; case GS_CMD_setCameraPositionOffsetXToFloatValue: if (game->inCombat) { VC3 tmp = game->gameUI->getGameCamera()->getPositionOffset(); tmp.x = gsd->floatValue; game->gameUI->getGameCamera()->setPositionOffset(tmp); } break; case GS_CMD_setCameraPositionOffsetYToFloatValue: if (game->inCombat) { VC3 tmp = game->gameUI->getGameCamera()->getPositionOffset(); tmp.y = gsd->floatValue; game->gameUI->getGameCamera()->setPositionOffset(tmp); } break; case GS_CMD_setCameraPositionOffsetZToFloatValue: if (game->inCombat) { VC3 tmp = game->gameUI->getGameCamera()->getPositionOffset(); tmp.z = gsd->floatValue; game->gameUI->getGameCamera()->setPositionOffset(tmp); } break; case GS_CMD_setCameraTargetOffsetXToFloatValue: if (game->inCombat) { VC3 tmp = game->gameUI->getGameCamera()->getTargetOffset(); tmp.x = gsd->floatValue; game->gameUI->getGameCamera()->setTargetOffset(tmp); } break; case GS_CMD_setCameraTargetOffsetYToFloatValue: if (game->inCombat) { VC3 tmp = game->gameUI->getGameCamera()->getTargetOffset(); tmp.y = gsd->floatValue; game->gameUI->getGameCamera()->setTargetOffset(tmp); } break; case GS_CMD_setCameraTargetOffsetZToFloatValue: if (game->inCombat) { VC3 tmp = game->gameUI->getGameCamera()->getTargetOffset(); tmp.z = gsd->floatValue; game->gameUI->getGameCamera()->setTargetOffset(tmp); } break; case GS_CMD_setCameraTargetOffsetAtPosition: if (game->inCombat) { VC3 targpos = game->gameUI->getGameCamera()->getTargetPosition(); VC3 diff = gsd->position - targpos; game->gameUI->getGameCamera()->setTargetOffset(diff); } break; case GS_CMD_setCameraPositionOffsetAtPosition: if (game->inCombat) { VC3 campos = game->gameUI->getGameCamera()->getPosition(); VC3 diff = gsd->position - campos; game->gameUI->getGameCamera()->setPositionOffset(diff); } break; case GS_CMD_disableDirectCameraControls: if (game->inCombat) { game->gameUI->getGameCamera()->setDirectControlsEnabled(false); } break; case GS_CMD_enableDirectCameraControls: if (game->inCombat) { game->gameUI->getGameCamera()->setDirectControlsEnabled(true); } break; case GS_CMD_updateCamera: { game->gameUI->getGameCamera()->doMovement(0); } break; case GS_CMD_setCameraAreaType: { cameraAreaParameters.type = intData; } break; case GS_CMD_setCameraAreaCorner1ToPosition: { VC3 pos = gsd->position; cameraAreaParameters.corner[0] = pos; } break; case GS_CMD_setCameraAreaCorner2ToPosition: { VC3 pos = gsd->position; cameraAreaParameters.corner[1] = pos; } break; case GS_CMD_setCameraAreaCorner3ToPosition: { VC3 pos = gsd->position; cameraAreaParameters.corner[2] = pos; } break; case GS_CMD_setCameraAreaCorner4ToPosition: { VC3 pos = gsd->position; cameraAreaParameters.corner[3] = pos; } break; case GS_CMD_setCameraAreaFOV: { float floatData = intFloat.f; cameraAreaParameters.FOV = floatData; } break; case GS_CMD_setCameraAreaAngle: { float floatData = intFloat.f; cameraAreaParameters.angle = floatData; } break; case GS_CMD_setCameraAreaBetaAngle: { float floatData = intFloat.f; cameraAreaParameters.betaAngle = floatData; } break; case GS_CMD_setCameraAreaBank: { float floatData = intFloat.f; cameraAreaParameters.bank = floatData; } break; case GS_CMD_setCameraAreaOffsetX: { float floatData = intFloat.f; cameraAreaParameters.offset.x = floatData; } break; case GS_CMD_setCameraAreaOffsetY: { float floatData = intFloat.f; cameraAreaParameters.offset.y = floatData; } break; case GS_CMD_setCameraAreaOffsetZ: { float floatData = intFloat.f; cameraAreaParameters.offset.z = floatData; } break; case GS_CMD_setCameraAreaFollowX: { float floatData = intFloat.f; cameraAreaParameters.follow.x = floatData*0.01f; } break; case GS_CMD_setCameraAreaFollowY: { float floatData = intFloat.f; cameraAreaParameters.follow.y = floatData*0.01f; } break; case GS_CMD_setCameraAreaFollowZ: { float floatData = intFloat.f; cameraAreaParameters.follow.z = floatData*0.01f; } break; case GS_CMD_setCameraAreaTargetToPosition: { VC3 pos = gsd->position; cameraAreaParameters.target = pos; } break; case GS_CMD_setCameraAreaAnimation: { cameraAreaParameters.animation = stringData; } break; case GS_CMD_setCameraAreaGroup: { cameraAreaParameters.group = intData; } break; case GS_CMD_addCameraArea: { game->getGameUI()->getCameraSystem()->addCameraArea(new CameraAreaStreet(cameraAreaParameters.name, cameraAreaParameters.group, cameraAreaParameters.collision, cameraAreaParameters.corner[0], cameraAreaParameters.corner[1], cameraAreaParameters.corner[2], cameraAreaParameters.corner[3], cameraAreaParameters.angle, cameraAreaParameters.betaAngle, cameraAreaParameters.bank, cameraAreaParameters.distance, cameraAreaParameters.FOV, cameraAreaParameters.target, cameraAreaParameters.offset, cameraAreaParameters.follow, cameraAreaParameters.animation)); // initializeCameraAreaParameters(); } break; case GS_CMD_setCameraAreaAngleToValue: { float floatData = (float)(*lastValue); cameraAreaParameters.angle = floatData; } break; case GS_CMD_setCameraAreaName: { cameraAreaParameters.name = stringData; } break; case GS_CMD_setCameraAreaDistance: { float floatData = intFloat.f; cameraAreaParameters.distance = floatData; } break; case GS_CMD_setCameraAreaCollision: { cameraAreaParameters.type = intData; } break; case GS_CMD_actualCameraPosition: gsd->position = game->gameUI->getGameCamera()->getActualInterpolatedPosition(); break; case GS_CMD_moveCameraAngle: { float floatData = intFloat.f; game->getGameUI()->getCameraSystem()->moveCameraAngle(floatData); } break; case GS_CMD_moveCameraBetaAngle: { float floatData = intFloat.f; game->getGameUI()->getCameraSystem()->moveCameraBetaAngle(floatData); } break; case GS_CMD_moveCameraBank: { float floatData = intFloat.f; game->getGameUI()->getCameraSystem()->moveCameraBank(floatData); } break; case GS_CMD_moveCameraDistance: { float floatData = intFloat.f; game->getGameUI()->getCameraSystem()->moveCameraDistance(floatData); } break; case GS_CMD_moveCameraFOV: { float floatData = intFloat.f; game->getGameUI()->getCameraSystem()->moveCameraFOV(floatData); } break; case GS_CMD_clearCameraAreas: { game->getGameUI()->getCameraSystem()->clearCameraAreas(); } break; case GS_CMD_isCameraSelected: if (stringData != NULL) { // oh yeah! copy & paste programming ahead... if (strncmp(stringData, "cinematic1", 10) == 0) { *lastValue = game->gameUI->getCameraNumber() == GAMEUI_CAMERA_CINEMATIC1 ? 1 : 0; break; } if (strncmp(stringData, "cinematic2", 10) == 0) { *lastValue = game->gameUI->getCameraNumber() == GAMEUI_CAMERA_CINEMATIC2 ? 1 : 0; break; } if (strncmp(stringData, "normal", 6) == 0) { *lastValue = game->gameUI->getCameraNumber() == GAMEUI_CAMERA_NORMAL ? 1 : 0; break; } if (strncmp(stringData, "tactical", 8) == 0) { *lastValue = game->gameUI->getCameraNumber() == GAMEUI_CAMERA_TACTICAL ? 1 : 0; break; } *lastValue = 0; sp->error("GameScripting::process - isCameraSelected parameter bad."); } else { *lastValue = 0; sp->error("GameScripting::process - isCameraSelected parameter expected."); } break; default: sp->error("CameraScripting::process - Unknown command."); assert(0); } }
VC3 CameraAutotilter::getTilt(const VC3 &position, float alphaAngle) { VC3 ret = VC3(0,0,0); assert(gameMap != NULL); // FIXME: need to rotate based on camera!!! // if camera points to some other direction, tilt // won't work corretly!!! int px = gameMap->scaledToObstacleX(position.x); int py = gameMap->scaledToObstacleY(position.z); //assert(px >= 0 && py >= 0 && px < gameMap->getObstacleSizeX() // && py < gameMap->getObstacleSizeY()); if(px <= 0 || py < 0 || px >= gameMap->getObstacleSizeX() || py >= gameMap->getObstacleSizeY()) { return ret; } float rotAngle = 90 + alphaAngle; if (rotAngle < 0) rotAngle += 360; if (rotAngle >= 360) rotAngle -= 360; // FIXME: rotated_x_vec is not correct! // therefore, returned y-axis rotation result is incorrect!!! VC2 rotated_y_vec = VC2(sinf(UNIT_ANGLE_TO_RAD(rotAngle)), cosf(UNIT_ANGLE_TO_RAD(rotAngle))); VC2 rotated_x_vec = -VC2(cosf(UNIT_ANGLE_TO_RAD(rotAngle)), sinf(UNIT_ANGLE_TO_RAD(rotAngle))); int obstSizeX = gameMap->getObstacleSizeX(); int obstSizeY = gameMap->getObstacleSizeY(); for (int y = -1; y > -CAMERATILT_CHECK_DISTANCE; y--) { int tx = int(px + rotated_y_vec.x * float(y)); int ty = int(py + rotated_y_vec.y * float(y)); if (tx >= 0 && ty >= 0 && tx < obstSizeX && ty < obstSizeY) { if (gameMap->getObstacleHeight(tx, ty) > CAMERATILT_ABOVE_OBSTACLE_HEIGHT && !gameMap->isMovingObstacle(tx, ty)) { ret.x = float(-CAMERATILT_CHECK_DISTANCE - y) * 2; break; } } } int x; int minx = -CAMERATILT_CHECK_DISTANCE; for (x = 1; x < CAMERATILT_CHECK_DISTANCE; x++) { int tx = int(px + rotated_x_vec.x * float(x)); int ty = int(py + rotated_x_vec.y * float(x)); if (tx >= 0 && ty >= 0 && tx < obstSizeX && ty < obstSizeY) { if (gameMap->getObstacleHeight(tx, ty) > CAMERATILT_ABOVE_OBSTACLE_HEIGHT && !gameMap->isMovingObstacle(tx, ty)) { minx = -x; ret.y = float(CAMERATILT_CHECK_DISTANCE - x); break; } } } for (x = -1; x >= minx; x--) { int tx = int(px + rotated_x_vec.x * float(x)); int ty = int(py + rotated_x_vec.y * float(x)); if (tx >= 0 && ty >= 0 && tx < obstSizeX && ty < obstSizeY) { if (gameMap->getObstacleHeight(tx, ty) > CAMERATILT_ABOVE_OBSTACLE_HEIGHT && !gameMap->isMovingObstacle(tx, ty)) { if (x == minx) { ret.y = 0.0f; } else { ret.y = float(-CAMERATILT_CHECK_DISTANCE - x); } break; } } } ret.y = -ret.y; int curTime = Timer::getTime(); int timeDiff = curTime - lastTime; if (timeDiff > 100) { timeDiff = 100; lastTime = curTime; } if (timeDiff < 0) { timeDiff = 0; lastTime = curTime; } if (lastTime < curTime) lastTime += timeDiff; float confFactor = 0.02f * game::SimpleOptions::getInt(DH_OPT_I_CAMERA_AUTOTILT_AMOUNT); if (fabs(ret.y - lastRotation.y) <= 2 * confFactor) { ret.y = lastRotation.y; } if (fabs(ret.x - lastRotation.x) <= 2 * confFactor) { ret.x = lastRotation.x; } float timeFactor = confFactor * 0.01f * float(timeDiff); VC3 posDiffVector = position - lastPosition; VC3 posDiffVectorRotated = VC3( posDiffVector.x * cosf(UNIT_ANGLE_TO_RAD(rotAngle)) + posDiffVector.z * sinf(UNIT_ANGLE_TO_RAD(rotAngle)), 0, posDiffVector.x * sinf(UNIT_ANGLE_TO_RAD(rotAngle)) + posDiffVector.z * cosf(UNIT_ANGLE_TO_RAD(rotAngle))); //if (posDiffVectorRotated.z < -0.01f) // Logger::getInstance()->error("z m"); //if (posDiffVectorRotated.z > 0.01f) // Logger::getInstance()->error("z p"); if (ret.x < lastRotation.x) { //if (position.z < lastPosition.z) //if (posDiffVectorRotated.z < -0.01f) ret.x = lastRotation.x - timeFactor; //else // ret.x = lastRotation.x; } if (ret.x > lastRotation.x) { //if (position.z > lastPosition.z) //if (posDiffVectorRotated.z > 0.01f) ret.x = lastRotation.x + timeFactor; //else // ret.x = lastRotation.x; } if (ret.y < lastRotation.y) { //if (position.x > lastPosition.x) //if (posDiffVectorRotated.x < -0.01f) ret.y = lastRotation.y - timeFactor; //else // ret.y = lastRotation.y; } if (ret.y > lastRotation.y) { //if (position.x < lastPosition.x) //if (posDiffVectorRotated.x > 0.01f) ret.y = lastRotation.y + timeFactor; //else // ret.y = lastRotation.y; } lastRotation = ret; lastPosition = position; return ret; }