384 lines
10 KiB
C
Raw Normal View History

2013-08-29 11:45:22 +09:00
/*
Copyright (c) 2013 yvt
2013-09-05 00:52:03 +09:00
based on code of pysnip (c) Mathias Kaerlev 2011-2012.
2013-08-29 11:45:22 +09:00
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
2013-08-18 16:18:06 +09:00
#pragma once
#include <string>
#include "Player.h"
#include "IWorldListener.h"
#include "ILocalEntity.h"
#include <Core/Math.h>
#include <Core/ServerAddress.h>
2013-08-18 16:18:06 +09:00
#include "IRenderer.h"
#include <list>
2013-11-22 22:50:14 +09:00
#include <Gui/View.h>
2014-03-09 21:43:38 +09:00
#include <memory>
2014-03-31 23:09:47 +09:00
#include <Core/Stopwatch.h>
2013-08-18 16:18:06 +09:00
namespace spades {
2013-08-26 19:24:15 +09:00
class IStream;
2014-03-31 23:09:47 +09:00
class Stopwatch;
2013-08-18 16:18:06 +09:00
namespace client {
class IRenderer;
struct SceneDefinition;
class GameMap;
class GameMapWrapper;
class World;
struct PlayerInput;
struct WeaponInput;
class IAudioDevice;
class IAudioChunk;
class NetClient;
class IFont;
class ChatWindow;
class CenterMessageView;
class Corpse;
class HurtRingView;
class MapView;
class ScoreboardView;
class LimboView;
class Player;
class PaletteView;
class TCProgressView;
class ClientPlayer;
2013-08-18 16:18:06 +09:00
2013-11-27 16:30:54 +09:00
class ClientUI;
2013-11-22 22:50:14 +09:00
class Client: public IWorldListener, public gui::View {
2013-08-18 16:18:06 +09:00
friend class ScoreboardView;
friend class LimboView;
friend class MapView;
friend class FallingBlock;
friend class PaletteView;
friend class TCProgressView;
friend class ClientPlayer;
2013-12-02 19:42:38 +09:00
friend class ClientUI;
2013-08-18 16:18:06 +09:00
/** used to keep the input state of keypad so that
2014-03-09 21:43:38 +09:00
* after user pressed left and right, and then
2013-08-18 16:18:06 +09:00
* released right, left is internally pressed. */
struct KeypadInput {
bool left, right, forward, backward;
KeypadInput():
left(false),right(false),
forward(false),backward(false){
}
};
2014-03-31 23:09:47 +09:00
class FPSCounter {
Stopwatch sw;
int numFrames;
double lastFps;
public:
FPSCounter();
void MarkFrame();
double GetFps() { return lastFps; }
};
FPSCounter fpsCounter;
2014-03-09 21:43:38 +09:00
std::unique_ptr<NetClient> net;
2013-08-18 16:18:06 +09:00
std::string playerName;
2014-03-09 21:43:38 +09:00
std::unique_ptr<IStream> logStream;
2013-08-18 16:18:06 +09:00
2013-11-27 16:30:54 +09:00
Handle<ClientUI> scriptedUI;
ServerAddress hostname;
2014-03-09 21:43:38 +09:00
std::unique_ptr<World> world;
Handle<GameMap> map;
std::unique_ptr<GameMapWrapper> mapWrapper;
Handle<IRenderer> renderer;
Handle<IAudioDevice> audioDevice;
2013-08-18 16:18:06 +09:00
float time;
bool readyToClose;
float worldSubFrame;
int frameToRendererInit;
float timeSinceInit;
// view/drawing state for some world objects
2014-03-09 21:43:38 +09:00
std::vector<Handle<ClientPlayer>> clientPlayers;
2013-08-18 16:18:06 +09:00
// other windows
2014-03-09 21:43:38 +09:00
std::unique_ptr<CenterMessageView> centerMessageView;
std::unique_ptr<HurtRingView> hurtRingView;
std::unique_ptr<MapView> mapView;
std::unique_ptr<MapView> largeMapView;
std::unique_ptr<ScoreboardView> scoreboard;
std::unique_ptr<LimboView> limbo;
std::unique_ptr<PaletteView> paletteView;
std::unique_ptr<TCProgressView> tcView;
2013-08-18 16:18:06 +09:00
// chat
2014-03-09 21:43:38 +09:00
std::unique_ptr<ChatWindow> chatWindow;
std::unique_ptr<ChatWindow> killfeedWindow;
2013-08-18 16:18:06 +09:00
// player state
PlayerInput playerInput;
WeaponInput weapInput;
KeypadInput keypadInput;
2014-03-13 01:44:58 +09:00
Player::ToolType lastTool;
bool hasLastTool;
2013-08-18 16:18:06 +09:00
Vector3 lastFront;
float lastPosSentTime;
int lastHealth;
float lastHurtTime;
float lastAliveTime;
int lastKills;
float worldSetTime;
bool hasDelayedReload;
2013-09-12 23:26:08 +09:00
struct HurtSprite {
float angle;
float horzShift;
float scale;
float strength;
};
std::vector<HurtSprite> hurtSprites;
float GetAimDownState();
float GetSprintState();
2013-08-18 16:18:06 +09:00
float toolRaiseState;
void SetSelectedTool(Player::ToolType, bool quiet = false);
2013-08-18 16:18:06 +09:00
// view
SceneDefinition lastSceneDef;
float localFireVibrationTime;
float grenadeVibration;
bool scoreboardVisible;
bool flashlightOn;
float flashlightOnTime;
2013-12-16 23:27:14 +09:00
float hitFeedbackIconState;
bool hitFeedbackFriendly;
2013-08-18 16:18:06 +09:00
// when dead...
/** Following player ID, which may be local player itself */
int followingPlayerId;
float followYaw, followPitch;
/** only for when spectating */
Vector3 followPos;
/** only for when spectating */
Vector3 followVel;
2014-03-08 00:23:26 +09:00
void FollowNextPlayer(bool reverse);
2013-08-18 16:18:06 +09:00
/** @return true following is activated (and followingPlayerId should be used) */
bool IsFollowing();
bool inGameLimbo;
float GetLocalFireVibration();
void CaptureColor();
bool IsLimboViewActive();
void SpawnPressed();
2013-10-19 02:00:42 +02:00
Player *HotTrackedPlayer( hitTag_t* hitFlag );
2013-08-18 16:18:06 +09:00
// effects (local entity, etc)
std::vector<DynamicLightParam> flashDlights;
std::vector<DynamicLightParam> flashDlightsOld;
void Bleed(Vector3);
void EmitBlockFragments(Vector3, IntVector3 color);
void EmitBlockDestroyFragments(IntVector3, IntVector3 color);
void GrenadeExplosion(Vector3);
void GrenadeExplosionUnderwater(Vector3);
void MuzzleFire(Vector3, Vector3 dir, bool local);
2014-03-12 03:38:45 +09:00
void BulletHitWaterSurface(Vector3);
2013-08-18 16:18:06 +09:00
// drawings
2014-03-09 21:43:38 +09:00
Handle<IFont> designFont;
Handle<IFont> textFont;
Handle<IFont> bigTextFont;
2013-08-18 16:18:06 +09:00
2014-03-11 03:42:04 +09:00
enum class AlertType {
Notice,
Warning,
Error
};
AlertType alertType;
std::string alertContents;
float alertDisappearTime;
float alertAppearTime;
2014-03-09 21:43:38 +09:00
std::list<std::unique_ptr<ILocalEntity>> localEntities;
std::list<std::unique_ptr<Corpse>> corpses;
2013-08-18 16:18:06 +09:00
Corpse *lastMyCorpse;
float corpseSoftTimeLimit;
2013-09-20 23:03:32 +02:00
unsigned int corpseSoftLimit;
unsigned int corpseHardLimit;
2014-03-09 21:43:38 +09:00
void RemoveAllCorpses();
void RemoveInvisibleCorpses();
void RemoveAllLocalEntities();
2013-08-18 16:18:06 +09:00
int nextScreenShotIndex;
2013-11-22 19:34:20 +09:00
int nextMapShotIndex;
2013-08-18 16:18:06 +09:00
Vector3 Project(Vector3);
void DrawSplash();
void DrawStartupScreen();
void DoInit();
2014-03-11 03:42:04 +09:00
void ShowAlert(const std::string& contents,
AlertType type);
void ShowAlert(const std::string& contents,
AlertType type,
float timeout,
bool quiet = false);
void PlayAlertSound();
2014-03-09 21:43:38 +09:00
void UpdateWorld(float dt);
void UpdateLocalSpectator(float dt);
void UpdateLocalPlayer(float dt);
2013-08-18 16:18:06 +09:00
void Draw2D();
2014-03-09 21:43:38 +09:00
void Draw2DWithoutWorld();
void Draw2DWithWorld();
void DrawJoinedAlivePlayerHUD();
void DrawDeadPlayerHUD();
void DrawSpectateHUD();
void DrawHottrackedPlayerName();
void DrawHurtScreenEffect();
2013-09-12 23:26:08 +09:00
void DrawHurtSprites();
2014-03-09 21:43:38 +09:00
void DrawHealth();
2014-03-11 03:42:04 +09:00
void DrawAlert();
2014-03-09 21:43:38 +09:00
void DrawDebugAim();
2014-03-31 23:09:47 +09:00
void DrawStats();
2014-03-09 21:43:38 +09:00
void DrawScene();
void AddGrenadeToScene(Grenade *);
void AddDebugObjectToScene(const OBB3&,
const Vector4& col = MakeVector4(1,1,1,1));
void DrawCTFObjects();
void DrawTCObjects();
float GetAimDownZoomScale();
bool ShouldRenderInThirdPersonView();
SceneDefinition CreateSceneDefinition();
2013-08-18 16:18:06 +09:00
std::string ScreenShotPath();
void TakeScreenShot(bool sceneOnly);
2013-11-22 19:34:20 +09:00
std::string MapShotPath();
void TakeMapShot();
2013-08-26 19:24:15 +09:00
void NetLog(const char *format, ...);
2013-11-22 22:50:14 +09:00
protected:
virtual ~Client();
2013-08-26 19:24:15 +09:00
2013-08-18 16:18:06 +09:00
public:
Client(IRenderer *, IAudioDevice *,
const ServerAddress& host, std::string playerName);
2013-08-18 16:18:06 +09:00
2013-11-22 22:50:14 +09:00
virtual void RunFrame(float dt);
2013-08-18 16:18:06 +09:00
2013-11-22 22:50:14 +09:00
virtual void Closing();
virtual void MouseEvent(float x, float y);
2013-12-09 17:36:05 +09:00
virtual void WheelEvent(float x, float y);
2013-11-22 22:50:14 +09:00
virtual void KeyEvent(const std::string&,
2013-12-09 17:36:05 +09:00
bool down);
virtual void TextInputEvent(const std::string&);
virtual void TextEditingEvent(const std::string&,
int start, int len);
virtual bool AcceptsTextInput();
virtual AABB2 GetTextInputRect();
2014-02-01 21:55:30 +09:00
virtual bool NeedsAbsoluteMouseCoordinate();
2013-08-18 16:18:06 +09:00
void SetWorld(World *);
2014-03-09 21:43:38 +09:00
World *GetWorld() const { return world.get(); }
2013-08-18 16:18:06 +09:00
void AddLocalEntity(ILocalEntity *ent){
2014-03-09 21:43:38 +09:00
localEntities.emplace_back(ent);
2013-08-18 16:18:06 +09:00
}
2014-03-09 21:43:38 +09:00
IRenderer *GetRenderer() {return renderer;}
SceneDefinition GetLastSceneDef() { return lastSceneDef; }
IAudioDevice *GetAudioDevice() {return audioDevice; }
2013-08-18 16:18:06 +09:00
2013-11-22 22:50:14 +09:00
virtual bool WantsToBeClosed();
2013-08-18 16:18:06 +09:00
bool IsMuted();
void PlayerSentChatMessage(Player *, bool global,
const std::string&);
void ServerSentMessage(const std::string&);
void PlayerCapturedIntel(Player *);
void PlayerCreatedBlock(Player *);
void PlayerPickedIntel(Player *);
void PlayerDropIntel(Player *);
void TeamCapturedTerritory(int teamId, int territoryId);
void TeamWon(int);
void JoinedGame();
void LocalPlayerCreated();
void PlayerDestroyedBlockWithWeaponOrTool(IntVector3);
void PlayerDiggedBlock(IntVector3);
void GrenadeDestroyedBlock(IntVector3);
void PlayerLeaving(Player *);
void PlayerJoinedTeam(Player *);
2013-08-18 16:18:06 +09:00
virtual void PlayerObjectSet(int);
2013-08-18 16:18:06 +09:00
virtual void PlayerMadeFootstep(Player *);
virtual void PlayerJumped(Player *);
virtual void PlayerLanded(Player *, bool hurt);
virtual void PlayerFiredWeapon(Player *);
virtual void PlayerDryFiredWeapon(Player *);
virtual void PlayerReloadingWeapon(Player *);
virtual void PlayerReloadedWeapon(Player *);
virtual void PlayerChangedTool(Player *);
virtual void PlayerThrownGrenade(Player *, Grenade *);
virtual void PlayerMissedSpade(Player *);
virtual void PlayerRestocked(Player *);
/** @deprecated use BulletHitPlayer */
virtual void PlayerHitBlockWithSpade(Player *,
Vector3 hitPos,
IntVector3 blockPos,
IntVector3 normal);
virtual void PlayerKilledPlayer(Player *killer,
Player *victim,
KillType);
virtual void BulletHitPlayer(Player *hurtPlayer, HitType,
Vector3 hitPos,
Player *by);
virtual void BulletHitBlock(Vector3,
IntVector3 blockPos,
IntVector3 normal);
2013-08-30 22:23:05 +09:00
virtual void AddBulletTracer(Player *player,
Vector3 muzzlePos,
Vector3 hitPos);
2013-08-18 16:18:06 +09:00
virtual void GrenadeExploded(Grenade *);
virtual void GrenadeBounced(Grenade *);
virtual void GrenadeDroppedIntoWater(Grenade *);
virtual void BlocksFell(std::vector<IntVector3>);
virtual void LocalPlayerPulledGrenadePin();
virtual void LocalPlayerBlockAction(IntVector3, BlockActionType type);
virtual void LocalPlayerCreatedLineBlock(IntVector3, IntVector3);
virtual void LocalPlayerHurt(HurtType type, bool sourceGiven,
Vector3 source);
2014-03-11 03:42:04 +09:00
virtual void LocalPlayerBuildError(BuildFailureReason reason);
2013-08-18 16:18:06 +09:00
};
}
}