1 /** @file clientplayer.cpp  Client-side player state.
2  *
3  * @authors Copyright (c) 2015-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
4  *
5  * @par License
6  * GPL: http://www.gnu.org/licenses/gpl.html
7  *
8  * <small>This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2 of the License, or (at your
11  * option) any later version. This program is distributed in the hope that it
12  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14  * Public License for more details. You should have received a copy of the GNU
15  * General Public License along with this program; if not, see:
16  * http://www.gnu.org/licenses</small>
17  */
18 
19 #include "clientplayer.h"
20 #include "render/consoleeffect.h"
21 #include "render/playerweaponanimator.h"
22 #include "ui/viewcompositor.h"
23 #include "def_share.h"
24 
25 #include <doomsday/world/world.h>
26 
27 using namespace de;
28 
DENG2_PIMPL(ClientPlayer)29 DENG2_PIMPL(ClientPlayer)
30 , DENG2_OBSERVES(World, MapChange)
31 {
32     ViewCompositor     viewCompositor;
33     viewdata_t         viewport;
34     ConsoleEffectStack effects;
35     render::PlayerWeaponAnimator playerWeaponAnimator;
36     clplayerstate_t    clPlayerState;
37     DemoTimer          demoTimer;
38 
39     state_t const *lastPSpriteState = nullptr;
40     String weaponAssetId;
41 
42     Impl(Public *i)
43         : Base(i)
44         , playerWeaponAnimator(i)
45     {
46         zap(clPlayerState);
47         zap(demoTimer);
48     }
49 
50     void worldMapChanged()
51     {
52         // Reset the weapon animator when the map changes.
53         if (playerWeaponAnimator.assetId())
54         {
55             playerWeaponAnimator.setAsset(playerWeaponAnimator.assetId());
56         }
57     }
58 };
59 
ClientPlayer()60 ClientPlayer::ClientPlayer()
61     : recording(false)
62     , recordPaused(false)
63     , d(new Impl(this))
64 {}
65 
setWorld(World * world)66 void ClientPlayer::setWorld(World *world)
67 {
68     Player::setWorld(world);
69     if (world)
70     {
71         world->audienceForMapChange() += d;
72     }
73 }
74 
viewCompositor()75 ViewCompositor &ClientPlayer::viewCompositor()
76 {
77     return d->viewCompositor;
78 }
79 
viewport()80 viewdata_t &ClientPlayer::viewport()
81 {
82     return d->viewport;
83 }
84 
viewport() const85 viewdata_t const &ClientPlayer::viewport() const
86 {
87     return d->viewport;
88 }
89 
clPlayerState()90 clplayerstate_t &ClientPlayer::clPlayerState()
91 {
92     return d->clPlayerState;
93 }
94 
clPlayerState() const95 clplayerstate_t const &ClientPlayer::clPlayerState() const
96 {
97     return d->clPlayerState;
98 }
99 
fxStack()100 ConsoleEffectStack &ClientPlayer::fxStack()
101 {
102     return d->effects;
103 }
104 
fxStack() const105 ConsoleEffectStack const &ClientPlayer::fxStack() const
106 {
107     return d->effects;
108 }
109 
playerWeaponAnimator()110 render::PlayerWeaponAnimator &ClientPlayer::playerWeaponAnimator()
111 {
112     return d->playerWeaponAnimator;
113 }
114 
demoTimer()115 DemoTimer &ClientPlayer::demoTimer()
116 {
117     return d->demoTimer;
118 }
119 
tick(timespan_t elapsed)120 void ClientPlayer::tick(timespan_t elapsed)
121 {
122     if (!isInGame()) return;
123 
124     d->playerWeaponAnimator.advanceTime(elapsed);
125 }
126 
setWeaponAssetId(String const & id)127 void ClientPlayer::setWeaponAssetId(String const &id)
128 {
129     if (id != d->weaponAssetId)
130     {
131         LOG_RES_VERBOSE("Weapon asset: %s") << id;
132         d->weaponAssetId = id;
133         d->playerWeaponAnimator.setAsset("model.weapon." + id);
134         d->playerWeaponAnimator.stateChanged(d->lastPSpriteState);
135     }
136 }
137 
weaponStateChanged(state_t const * state)138 void ClientPlayer::weaponStateChanged(state_t const *state)
139 {
140     if (state != d->lastPSpriteState)
141     {
142         d->lastPSpriteState = state;
143         d->playerWeaponAnimator.stateChanged(state);
144     }
145 }
146