Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
Character.cpp
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5 Copyright 2017-2018 Petr Ohlidal
6
7 For more information, see http://www.rigsofrods.org/
8
9 Rigs of Rods is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 3, as
11 published by the Free Software Foundation.
12
13 Rigs of Rods is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "Character.h"
23
24#include "Application.h"
25#include "Actor.h"
26#include "ActorManager.h"
27#include "CameraManager.h"
28#include "Collisions.h"
29#include "GameContext.h"
30#include "GfxScene.h"
31#include "InputEngine.h"
32#include "MovableText.h"
33#include "Network.h"
34#include "Terrain.h"
35#include "Utils.h"
36#include "GfxWater.h"
37
38using namespace Ogre;
39using namespace RoR;
40
41#define LOGSTREAM Ogre::LogManager::getSingleton().stream()
42
43Character::Character(int source, unsigned int streamid, std::string player_name, int color_number, bool is_remote) :
44 m_actor_coupling(nullptr)
45 , m_can_jump(false)
46 , m_character_rotation(0.0f)
47 , m_character_h_speed(2.0f)
48 , m_character_v_speed(0.0f)
49 , m_color_number(color_number)
50 , m_anim_time(0.f)
51 , m_net_last_anim_time(0.f)
52 , m_net_last_update_time(0.f)
53 , m_net_username(player_name)
54 , m_is_remote(is_remote)
55 , m_source_id(source)
56 , m_stream_id(streamid)
57 , m_gfx_character(nullptr)
58 , m_driving_anim_length(0.f)
59 , m_anim_name("Idle_sway")
60{
61 static int id_counter = 0;
62 m_instance_name = "Character#" + TOSTRING(id_counter);
63 ++id_counter;
64
65 if (App::mp_state->getEnum<MpState>() == MpState::CONNECTED)
66 {
67 this->SendStreamSetup();
68 }
69}
70
79
84
85void Character::setPosition(Vector3 position) // TODO: updates OGRE objects --> belongs to GfxScene ~ only_a_ptr, 05/2018
86{
87 //ASYNCSCENE OLD m_character_scenenode->setPosition(position);
88 m_character_position = position;
89 m_prev_position = position;
90}
91
93{
94 //ASYNCSCENE OLDreturn m_character_scenenode->getPosition();
96}
97
98void Character::setRotation(Radian rotation)
99{
100 m_character_rotation = rotation;
101}
102
103void Character::SetAnimState(std::string mode, float time)
104{
105 if (m_anim_name != mode)
106 {
107 m_anim_name = mode;
108 m_anim_time = time;
110 }
111 else
112 {
113 m_anim_time += time;
114 }
115}
116
118{
119 Vector3 query = pos + 0.3f * Vector3::UNIT_Y;
120 while (query.y > pos.y)
121 {
122 if (App::GetGameContext()->GetTerrain()->GetCollisions()->collisionCorrect(&query, false))
123 break;
124 query.y -= 0.001f;
125 }
126 return query.y - pos.y;
127}
128
129void Character::update(float dt)
130{
131 if (!m_is_remote && (m_actor_coupling == nullptr) && (App::sim_state->getEnum<SimState>() != SimState::PAUSED))
132 {
133 // disable character movement when using the free camera mode or when the menu is opened
134 // TODO: check for menu being opened
135 if (App::GetCameraManager()->GetCurrentBehavior() == CameraManager::CAMERA_BEHAVIOR_FREE)
136 {
137 return;
138 }
139
140 Vector3 position = m_character_position; //ASYNCSCENE OLD m_character_scenenode->getPosition();
141
142 // gravity force is always on
143 position.y += m_character_v_speed * dt;
144 m_character_v_speed += dt * -9.8f;
145
146 // Trigger script events and handle mesh (ground) collision
147 Vector3 query = position;
149
150 // Auto compensate minor height differences
151 float depth = calculate_collision_depth(position);
152 if (depth > 0.0f)
153 {
154 m_can_jump = true;
156 position.y += std::min(depth, 2.0f * dt);
157 }
158
159 // Submesh "collision"
160 {
161 float depth = 0.0f;
163 {
164 if (actor->ar_bounding_box.contains(position))
165 {
166 for (int i = 0; i < actor->ar_num_collcabs; i++)
167 {
168 int tmpv = actor->ar_collcabs[i] * 3;
169 Vector3 a = actor->ar_nodes[actor->ar_cabs[tmpv + 0]].AbsPosition;
170 Vector3 b = actor->ar_nodes[actor->ar_cabs[tmpv + 1]].AbsPosition;
171 Vector3 c = actor->ar_nodes[actor->ar_cabs[tmpv + 2]].AbsPosition;
172 auto result = Math::intersects(Ray(position, Vector3::UNIT_Y), a, b, c);
173 if (result.first && result.second < 1.8f)
174 {
175 depth = std::max(depth, result.second);
176 }
177 }
178 }
179 }
180 if (depth > 0.0f)
181 {
182 m_can_jump = true;
184 position.y += std::min(depth, 0.05f);
185 }
186 }
187
188 // Obstacle detection
189 if (position != m_prev_position)
190 {
191 const int numstep = 100;
192 Vector3 diff = position - m_prev_position;
193 Vector3 base = m_prev_position + Vector3::UNIT_Y * 0.25f;
194 for (int i = 1; i < numstep; i++)
195 {
196 Vector3 query_ = base + diff * ((float)i / numstep);
197 if (App::GetGameContext()->GetTerrain()->GetCollisions()->collisionCorrect(&query_, false))
198 {
200 position = m_prev_position + diff * ((float)(i - 1) / numstep);
201 position.y += 0.025f;
202 break;
203 }
204 }
205 }
206
207 m_prev_position = position;
208
209 // ground contact
210 float pheight = App::GetGameContext()->GetTerrain()->getHeightAt(position.x, position.z);
211
212 if (position.y < pheight)
213 {
214 position.y = pheight;
215 m_character_v_speed = 0.0f;
216 m_can_jump = true;
217 }
218
219 // water stuff
220 bool isswimming = false;
221 float wheight = -99999;
222
223 if (App::GetGameContext()->GetTerrain()->getWater())
224 {
225 wheight = App::GetGameContext()->GetTerrain()->getWater()->CalcWavesHeight(position);
226 if (position.y < wheight - 1.8f)
227 {
228 position.y = wheight - 1.8f;
229 m_character_v_speed = 0.0f;
230 }
231 }
232
233 // 0.1 due to 'jumping' from waves -> not nice looking
234 if (App::GetGameContext()->GetTerrain()->getWater() && (wheight - pheight > 1.8f) && (position.y + 0.1f <= wheight))
235 {
236 isswimming = true;
237 }
238
239 float tmpJoy = 0.0f;
240 if (m_can_jump)
241 {
242 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CHARACTER_JUMP))
243 {
244 m_character_v_speed = 2.0f;
245 m_can_jump = false;
246 }
247 }
248
249 bool idleanim = true;
254 bool not_walking = (tmpGoForward == 0.f && tmpGoBackward == 0.f);
255
257 if (tmpJoy > 0.0f)
258 {
259 float scale = RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LMENU) ? 0.1f : 1.0f;
260 setRotation(m_character_rotation + dt * 2.0f * scale * Radian(tmpJoy));
261 if (!isswimming && not_walking)
262 {
263 this->SetAnimState("Turn", -dt);
264 idleanim = false;
265 }
266 }
267
269 if (tmpJoy > 0.0f)
270 {
271 float scale = RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LMENU) ? 0.1f : 1.0f;
272 setRotation(m_character_rotation - dt * scale * 2.0f * Radian(tmpJoy));
273 if (!isswimming && not_walking)
274 {
275 this->SetAnimState("Turn", dt);
276 idleanim = false;
277 }
278 }
279
281 float accel = 1.0f;
282
284 if (tmpJoy > 0.0f)
285 {
286 if (tmpRun > 0.0f)
287 accel = 3.0f * tmpRun;
288 // animation missing for that
289 position += dt * m_character_h_speed * 0.5f * accel * Vector3(cos(m_character_rotation.valueRadians() - Math::HALF_PI), 0.0f, sin(m_character_rotation.valueRadians() - Math::HALF_PI));
290 if (!isswimming && not_walking)
291 {
292 this->SetAnimState("Side_step", -dt);
293 idleanim = false;
294 }
295 }
296
298 if (tmpJoy > 0.0f)
299 {
300 if (tmpRun > 0.0f)
301 accel = 3.0f * tmpRun;
302 // animation missing for that
303 position += dt * m_character_h_speed * 0.5f * accel * Vector3(cos(m_character_rotation.valueRadians() + Math::HALF_PI), 0.0f, sin(m_character_rotation.valueRadians() + Math::HALF_PI));
304 if (!isswimming && not_walking)
305 {
306 this->SetAnimState("Side_step", dt);
307 idleanim = false;
308 }
309 }
310
311 tmpJoy = accel = tmpGoForward;
312 float tmpBack = tmpGoBackward;
313
314 tmpJoy = std::min(tmpJoy, 1.0f);
315 tmpBack = std::min(tmpBack, 1.0f);
316
317 if (tmpJoy > 0.0f || tmpRun > 0.0f)
318 {
319 if (tmpRun > 0.0f)
320 accel = 3.0f * tmpRun;
321
322 float time = dt * tmpJoy * m_character_h_speed;
323
324 if (isswimming)
325 {
326 this->SetAnimState("Swim_loop", time);
327 idleanim = false;
328 }
329 else
330 {
331 if (tmpRun > 0.0f)
332 {
333 this->SetAnimState("Run", time);
334 idleanim = false;
335 }
336 else
337 {
338 this->SetAnimState("Walk", time);
339 idleanim = false;
340 }
341 }
342 position += dt * m_character_h_speed * 1.5f * accel * Vector3(cos(m_character_rotation.valueRadians()), 0.0f, sin(m_character_rotation.valueRadians()));
343 }
344 else if (tmpBack > 0.0f)
345 {
346 float time = -dt * m_character_h_speed;
347 if (isswimming)
348 {
349 this->SetAnimState("Spot_swim", time);
350 idleanim = false;
351 }
352 else
353 {
354 this->SetAnimState("Walk", time);
355 idleanim = false;
356 }
357 position -= dt * m_character_h_speed * tmpBack * Vector3(cos(m_character_rotation.valueRadians()), 0.0f, sin(m_character_rotation.valueRadians()));
358 }
359
360 if (idleanim)
361 {
362 if (isswimming)
363 {
364 this->SetAnimState("Spot_swim", dt * 2.0f);
365 }
366 else
367 {
368 this->SetAnimState("Idle_sway", dt * 1.0f);
369 }
370 }
371
372 m_character_position = position;
373 }
374 else if (m_actor_coupling) // The character occupies a vehicle or machine
375 {
376 // Animation
377 float angle = m_actor_coupling->ar_hydro_dir_wheel_display * -1.0f; // not getSteeringAngle(), but this, as its smoothed
378 float anim_time_pos = ((angle + 1.0f) * 0.5f) * m_driving_anim_length;
379 // prevent animation flickering on the borders:
380 if (anim_time_pos < 0.01f)
381 {
382 anim_time_pos = 0.01f;
383 }
384 if (anim_time_pos > m_driving_anim_length - 0.01f)
385 {
386 anim_time_pos = m_driving_anim_length - 0.01f;
387 }
388 m_anim_name = "Driving";
389 m_anim_time = anim_time_pos;
391 }
392
393#ifdef USE_SOCKETW
394 if ((App::mp_state->getEnum<MpState>() == MpState::CONNECTED) && !m_is_remote)
395 {
396 this->SendStreamData();
397 }
398#endif // USE_SOCKETW
399}
400
401void Character::move(Vector3 offset)
402{
403 m_character_position += offset; //ASYNCSCENE OLD m_character_scenenode->translate(offset);
404}
405
406// Helper function
407void Character::ReportError(const char* detail)
408{
409#ifdef USE_SOCKETW
410 std::string username;
411 RoRnet::UserInfo info;
412 if (!App::GetNetwork()->GetUserInfo(m_source_id, info))
413 username = "~~ERROR getting username~~";
414 else
415 username = info.username;
416
417 char msg_buf[300];
418 snprintf(msg_buf, 300,
419 "[RoR|Networking] ERROR on m_is_remote character (User: '%s', SourceID: %d, StreamID: %d): ",
420 username.c_str(), m_source_id, m_stream_id);
421
422 LOGSTREAM << msg_buf << detail;
423#endif
424}
425
427{
428#ifdef USE_SOCKETW
429 if (m_is_remote)
430 return;
431
433 memset(&reg, 0, sizeof(reg));
434 reg.status = 1;
435 strcpy(reg.name, "default");
436 reg.type = 1;
437 reg.data[0] = 2;
438
440
443#endif // USE_SOCKETW
444}
445
447{
448#ifdef USE_SOCKETW
449 if (m_net_timer.getMilliseconds() - m_net_last_update_time < 100)
450 return;
451
452 // do not send position data if coupled to an actor already
454 return;
455
456 m_net_last_update_time = m_net_timer.getMilliseconds();
457
463 msg.rot_angle = m_character_rotation.valueRadians();
464 strncpy(msg.anim_name, m_anim_name.c_str(), CHARACTER_ANIM_NAME_LEN);
466
468
470#endif // USE_SOCKETW
471}
472
473void Character::receiveStreamData(unsigned int& type, int& source, unsigned int& streamid, char* buffer)
474{
475#ifdef USE_SOCKETW
476 if (type == RoRnet::MSG2_STREAM_DATA && m_source_id == source && m_stream_id == streamid)
477 {
478 auto* msg = reinterpret_cast<NetCharacterMsgGeneric*>(buffer);
479 if (msg->command == CHARACTER_CMD_POSITION)
480 {
481 auto* pos_msg = reinterpret_cast<NetCharacterMsgPos*>(buffer);
482 this->setPosition(Ogre::Vector3(pos_msg->pos_x, pos_msg->pos_y, pos_msg->pos_z));
483 this->setRotation(Ogre::Radian(pos_msg->rot_angle));
485 {
486 this->SetAnimState(pos_msg->anim_name, pos_msg->anim_time);
487 }
488 }
489 else if (msg->command == CHARACTER_CMD_DETACH)
490 {
491 if (m_actor_coupling != nullptr)
492 this->SetActorCoupling(false, nullptr);
493 else
494 this->ReportError("Received command `DETACH`, but not currently attached to a vehicle. Ignoring command.");
495 }
496 else if (msg->command == CHARACTER_CMD_ATTACH)
497 {
498 auto* attach_msg = reinterpret_cast<NetCharacterMsgAttach*>(buffer);
499 ActorPtr beam = App::GetGameContext()->GetActorManager()->GetActorByNetworkLinks(attach_msg->source_id, attach_msg->stream_id);
500 if (beam != nullptr)
501 {
502 this->SetActorCoupling(true, beam);
503 }
504 else
505 {
506 char err_buf[200];
507 snprintf(err_buf, 200, "Received command `ATTACH` with target{SourceID: %d, StreamID: %d}, "
508 "but corresponding vehicle doesn't exist. Ignoring command.",
509 attach_msg->source_id, attach_msg->stream_id);
510 this->ReportError(err_buf);
511 }
512 }
513 else
514 {
515 char err_buf[100];
516 snprintf(err_buf, 100, "Received invalid command: %d. Cannot process.", msg->command);
517 this->ReportError(err_buf);
518 }
519 }
520#endif
521}
522
523void Character::SetActorCoupling(bool enabled, ActorPtr actor)
524{
525 m_actor_coupling = actor;
526#ifdef USE_SOCKETW
527 if (App::mp_state->getEnum<MpState>() == MpState::CONNECTED && !m_is_remote)
528 {
529 if (enabled)
530 {
536 }
537 else
538 {
542 }
543 }
544#endif // USE_SOCKETW
545}
546
548
549// --------------------------------
550// GfxCharacter
551
553{
554 Entity* entity = App::GetGfxScene()->GetSceneManager()->createEntity(m_instance_name + "_mesh", "character.mesh");
555 m_driving_anim_length = entity->getAnimationState("Driving")->getLength();
556
557 // fix disappearing mesh
558 AxisAlignedBox aabb;
559 aabb.setInfinite();
560 entity->getMesh()->_setBounds(aabb);
561
562 // add entity to the scene node
563 Ogre::SceneNode* scenenode = App::GetGfxScene()->GetSceneManager()->getRootSceneNode()->createChildSceneNode(m_instance_name);
564 scenenode->attachObject(entity);
565 scenenode->setScale(0.02f, 0.02f, 0.02f);
566 scenenode->setVisible(false);
567
568 // setup colour
569 MaterialPtr mat1 = MaterialManager::getSingleton().getByName("tracks/character");
570 MaterialPtr mat2 = mat1->clone("tracks/" + m_instance_name);
571 entity->setMaterialName("tracks/" + m_instance_name);
572
574 m_gfx_character->xc_scenenode = scenenode;
577
578 return m_gfx_character;
579}
580
582{
583 Entity* ent = static_cast<Ogre::Entity*>(xc_scenenode->getAttachedObject(0));
584 xc_scenenode->detachAllObjects();
585 App::GetGfxScene()->GetSceneManager()->destroySceneNode(xc_scenenode);
586 App::GetGfxScene()->GetSceneManager()->destroyEntity(ent);
587 MaterialManager::getSingleton().unload("tracks/" + xc_instance_name);
588}
589
591{
592 xc_simbuf_prev = xc_simbuf;
593
594 xc_simbuf.simbuf_character_pos = xc_character->getPosition();
595 xc_simbuf.simbuf_character_rot = xc_character->getRotation();
596 xc_simbuf.simbuf_color_number = xc_character->GetColorNum();
597 xc_simbuf.simbuf_net_username = xc_character->GetNetUsername();
598 xc_simbuf.simbuf_is_remote = xc_character->GetIsRemote();
599 xc_simbuf.simbuf_actor_coupling = xc_character->GetActorCoupling();
600 xc_simbuf.simbuf_anim_name = xc_character->GetAnimName();
601 xc_simbuf.simbuf_anim_time = xc_character->GetAnimTime();
602}
603
605{
606 // Actor coupling
607 if (xc_simbuf.simbuf_actor_coupling != xc_simbuf_prev.simbuf_actor_coupling)
608 {
609 if (xc_simbuf.simbuf_actor_coupling != nullptr)
610 {
611 // Entering/switching vehicle
612 xc_scenenode->getAttachedObject(0)->setCastShadows(false);
613 xc_scenenode->setVisible(xc_simbuf.simbuf_actor_coupling->GetGfxActor()->HasDriverSeatProp());
614 }
615 else if (xc_simbuf_prev.simbuf_actor_coupling != nullptr)
616 {
617 // Leaving vehicle
618 xc_scenenode->getAttachedObject(0)->setCastShadows(true);
619 xc_scenenode->resetOrientation();
620 }
621 }
622
623 // Position + Orientation
624 Ogre::Entity* entity = static_cast<Ogre::Entity*>(xc_scenenode->getAttachedObject(0));
625 if (xc_simbuf.simbuf_actor_coupling != nullptr)
626 {
627 // We're in vehicle
628 GfxActor* gfx_actor = xc_simbuf.simbuf_actor_coupling->GetGfxActor();
629
630 // Update character visibility first
631 switch (gfx_actor->GetSimDataBuffer().simbuf_actor_state)
632 {
634 entity->setVisible(false);
635 break;
637 entity->setVisible(gfx_actor->HasDriverSeatProp());
638 break;
639 default:
640 break; // no change.
641 }
642
643 // If visible, update position
644 if (entity->isVisible())
645 {
646 Ogre::Vector3 pos;
647 Ogre::Quaternion rot;
648 xc_simbuf.simbuf_actor_coupling->GetGfxActor()->CalculateDriverPos(pos, rot);
649 xc_scenenode->setOrientation(rot);
650 // hack to position the character right perfect on the default seat (because the mesh has decentered origin)
651 xc_scenenode->setPosition(pos + (rot * Vector3(0.f, -0.6f, 0.f)));
652 }
653 }
654 else
655 {
656 xc_scenenode->resetOrientation();
657 xc_scenenode->yaw(-xc_simbuf.simbuf_character_rot);
658 xc_scenenode->setPosition(xc_simbuf.simbuf_character_pos);
659 xc_scenenode->setVisible(true);
660 }
661
662 // Animation
663 if (xc_simbuf.simbuf_anim_name != xc_simbuf_prev.simbuf_anim_name)
664 {
665 // 'Classic' method - enable one anim, exterminate the others ~ only_a_ptr, 06/2018
666 AnimationStateIterator it = entity->getAllAnimationStates()->getAnimationStateIterator();
667
668 while (it.hasMoreElements())
669 {
670 AnimationState* as = it.getNext();
671
672 if (as->getAnimationName() == xc_simbuf.simbuf_anim_name)
673 {
674 as->setEnabled(true);
675 as->setWeight(1);
676 as->addTime(xc_simbuf.simbuf_anim_time);
677 }
678 else
679 {
680 as->setEnabled(false);
681 as->setWeight(0);
682 }
683 }
684 }
685 else if (xc_simbuf.simbuf_anim_name != "") // Just do nothing if animation name is empty. May happen during networked play.
686 {
687 auto* as_cur = entity->getAnimationState(xc_simbuf.simbuf_anim_name);
688 as_cur->setTimePosition(xc_simbuf.simbuf_anim_time);
689 }
690
691 // Multiplayer label
692#ifdef USE_SOCKETW
693 if (App::mp_state->getEnum<MpState>() == MpState::CONNECTED && !xc_simbuf.simbuf_actor_coupling)
694 {
695 // From 'updateCharacterNetworkColor()'
696 const String materialName = "tracks/" + xc_instance_name;
697
698 MaterialPtr mat = MaterialManager::getSingleton().getByName(materialName);
699 if (mat && mat->getNumTechniques() > 0 && mat->getTechnique(0)->getNumPasses() > 1 &&
700 mat->getTechnique(0)->getPass(1)->getNumTextureUnitStates() > 1)
701 {
702 const auto& state = mat->getTechnique(0)->getPass(1)->getTextureUnitState(1);
703 Ogre::ColourValue color = App::GetNetwork()->GetPlayerColor(xc_simbuf.simbuf_color_number);
704 state->setColourOperationEx(LBX_BLEND_CURRENT_ALPHA, LBS_MANUAL, LBS_CURRENT, color);
705 }
706
707 if ((!xc_simbuf.simbuf_is_remote && !App::mp_hide_own_net_label->getBool()) ||
708 (xc_simbuf.simbuf_is_remote && !App::mp_hide_net_labels->getBool()))
709 {
710 float camDist = (xc_scenenode->getPosition() - App::GetCameraManager()->GetCameraNode()->getPosition()).length();
711 Ogre::Vector3 scene_pos = xc_scenenode->getPosition();
712 scene_pos.y += (1.9f + camDist / 100.0f);
713
714 App::GetGfxScene()->DrawNetLabel(scene_pos, camDist, xc_simbuf.simbuf_net_username, xc_simbuf.simbuf_color_number);
715 }
716 }
717#endif // USE_SOCKETW
718}
Central state/object manager and communications hub.
#define CHARACTER_ANIM_NAME_LEN
Definition Application.h:42
#define TOSTRING(x)
Definition Application.h:57
float calculate_collision_depth(Vector3 pos)
Game state manager and message-queue provider.
#define strnlen(str, len)
Handles controller inputs from player.
This creates a billboarding object that displays a text.
static int id_counter
#define LOGSTREAM
int ar_net_source_id
Unique ID of remote player who spawned this actor.
Definition Actor.h:479
Ogre::Real ar_hydro_dir_wheel_display
Definition Actor.h:458
int ar_net_stream_id
Definition Actor.h:480
ActorPtrVec & GetActors()
const ActorPtr & GetActorByNetworkLinks(int source_id, int stream_id)
bool getBool() const
Definition CVar.h:98
Ogre::SceneNode * GetCameraNode()
GfxCharacter * SetupGfx()
void setPosition(Ogre::Vector3 position)
Definition Character.cpp:85
ActorPtr m_actor_coupling
The vehicle or machine which the character occupies.
Definition Character.h:73
Ogre::Vector3 getPosition()
Definition Character.cpp:92
void setRotation(Ogre::Radian rotation)
Definition Character.cpp:98
float m_driving_anim_length
Definition Character.h:87
void SendStreamData()
float m_character_v_speed
Definition Character.h:76
void update(float dt)
unsigned long m_net_last_update_time
Definition Character.h:91
Ogre::Vector3 m_prev_position
Definition Character.h:78
void receiveStreamData(unsigned int &type, int &source, unsigned int &streamid, char *buffer)
std::string m_anim_name
Definition Character.h:84
void SendStreamSetup()
float m_anim_time
Definition Character.h:85
void SetActorCoupling(bool enabled, ActorPtr actor)
float m_net_last_anim_time
Definition Character.h:86
ActorPtr GetActorCoupling()
GfxCharacter * m_gfx_character
Definition Character.h:92
Ogre::Radian m_character_rotation
Definition Character.h:74
Ogre::Vector3 m_character_position
Definition Character.h:77
void move(Ogre::Vector3 offset)
void SetAnimState(std::string mode, float time=0)
void updateCharacterRotation()
Definition Character.cpp:80
Ogre::Timer m_net_timer
Definition Character.h:90
std::string m_instance_name
Definition Character.h:88
float m_character_h_speed
Definition Character.h:75
Character(int source=-1, unsigned int streamid=0, std::string playerName="", int color_number=0, bool is_remote=true)
Definition Character.cpp:43
void ReportError(const char *detail)
bool collisionCorrect(Ogre::Vector3 *refpos, bool envokeScriptCallbacks=true)
const TerrainPtr & GetTerrain()
ActorManager * GetActorManager()
ActorSB & GetSimDataBuffer()
Definition GfxActor.h:128
bool HasDriverSeatProp() const
Definition GfxActor.h:151
void CalculateDriverPos(Ogre::Vector3 &out_pos, Ogre::Quaternion &out_rot)
void DrawNetLabel(Ogre::Vector3 pos, float cam_dist, std::string const &nick, int colornum)
Definition GfxScene.cpp:374
void RemoveGfxCharacter(RoR::GfxCharacter *gfx_character)
Definition GfxScene.cpp:365
Ogre::SceneManager * GetSceneManager()
Definition GfxScene.h:83
bool isKeyDown(OIS::KeyCode mod)
Asks OIS directly.
float getEventValue(int eventID, bool pure=false, InputSourceType valueSource=InputSourceType::IST_ANY)
valueSource: IST_ANY=digital and analog devices, IST_DIGITAL=only digital, IST_ANALOG=only analog
Ogre::ColourValue GetPlayerColor(int color_num)
Definition Network.cpp:94
void AddLocalStream(RoRnet::StreamRegister *reg, int size)
Definition Network.cpp:670
void AddPacket(int streamid, int type, int len, const char *content)
Definition Network.cpp:616
float getHeightAt(float x, float z)
Definition Terrain.cpp:512
Collisions * GetCollisions()
Definition Terrain.h:86
Wavefield * getWater()
Definition Terrain.h:87
float CalcWavesHeight(Vec3 pos, float timeshift_sec=0.f)
Definition Wavefield.cpp:90
@ EV_CHARACTER_ROT_UP
@ EV_CHARACTER_SIDESTEP_LEFT
sidestep to the left
@ EV_CHARACTER_RUN
let the character run
@ EV_CHARACTER_RIGHT
rotate character right
@ EV_CHARACTER_FORWARD
step forward with the character
@ EV_CHARACTER_LEFT
rotate character left
@ EV_CHARACTER_JUMP
let the character jump
@ EV_CHARACTER_ROT_DOWN
@ EV_CHARACTER_SIDESTEP_RIGHT
sidestep to the right
@ EV_CHARACTER_BACKWARDS
step backwards with the character
@ CHARACTER_CMD_ATTACH
Definition Network.h:61
@ CHARACTER_CMD_DETACH
Definition Network.h:62
@ CHARACTER_CMD_POSITION
Definition Network.h:60
@ NETWORKED_OK
not simulated (remote) actor
@ NETWORKED_HIDDEN
not simulated, not updated (remote)
CVar * mp_hide_own_net_label
CVar * sim_state
CVar * mp_hide_net_labels
InputEngine * GetInputEngine()
CameraManager * GetCameraManager()
GameContext * GetGameContext()
GfxScene * GetGfxScene()
CVar * mp_state
Network * GetNetwork()
@ MSG2_STREAM_DATA_DISCARDABLE
stream data that is allowed to be discarded
Definition RoRnet.h:67
@ MSG2_STREAM_DATA
stream data
Definition RoRnet.h:66
ActorState simbuf_actor_state
Definition SimBuffers.h:115
Character * xc_character
Definition Character.h:120
Ogre::SceneNode * xc_scenenode
Definition Character.h:117
std::string xc_instance_name
Definition Character.h:121
void UpdateCharacterInScene()
void BufferSimulationData()
char anim_name[CHARACTER_ANIM_NAME_LEN]
Definition Network.h:76
< Sent from the client to server and vice versa, to broadcast a new stream
Definition RoRnet.h:160
int32_t type
0 = Actor, 1 = Character, 3 = ChatSystem
Definition RoRnet.h:161
char data[128]
data used for stream setup
Definition RoRnet.h:166
int32_t origin_streamid
origin streamid
Definition RoRnet.h:164
int32_t origin_sourceid
origin sourceid
Definition RoRnet.h:163
char name[128]
file name
Definition RoRnet.h:165
int32_t status
initial stream status
Definition RoRnet.h:162
char username[RORNET_MAX_USERNAME_LEN]
the nickname of the user (UTF-8)
Definition RoRnet.h:196