41#define LOGSTREAM Ogre::LogManager::getSingleton().stream()
43Character::Character(
int source,
unsigned int streamid, std::string player_name,
int color_number,
bool is_remote) :
44 m_actor_coupling(nullptr)
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)
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)
56 , m_stream_id(streamid)
57 , m_gfx_character(nullptr)
58 , m_driving_anim_length(0.f)
59 , m_anim_name(
"Idle_sway")
43Character::Character(
int source,
unsigned int streamid, std::string player_name,
int color_number,
bool is_remote) : {
…}
119 Vector3 query = pos + 0.3f * Vector3::UNIT_Y;
120 while (query.y > pos.y)
126 return query.y - pos.y;
147 Vector3 query = position;
156 position.y += std::min(depth, 2.0f * dt);
164 if (actor->ar_bounding_box.contains(position))
166 for (
int i = 0; i < actor->ar_num_collcabs; i++)
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)
175 depth = std::max(depth, result.second);
184 position.y += std::min(depth, 0.05f);
191 const int numstep = 100;
194 for (
int i = 1; i < numstep; i++)
196 Vector3 query_ = base + diff * ((float)i / numstep);
197 if (
App::GetGameContext()->GetTerrain()->GetCollisions()->collisionCorrect(&query_,
false))
201 position.y += 0.025f;
212 if (position.y < pheight)
214 position.y = pheight;
220 bool isswimming =
false;
221 float wheight = -99999;
226 if (position.y < wheight - 1.8f)
228 position.y = wheight - 1.8f;
234 if (
App::GetGameContext()->GetTerrain()->getWater() && (wheight - pheight > 1.8f) && (position.y + 0.1f <= wheight))
249 bool idleanim =
true;
254 bool not_walking = (tmpGoForward == 0.f && tmpGoBackward == 0.f);
261 if (!isswimming && not_walking)
273 if (!isswimming && not_walking)
287 accel = 3.0f * tmpRun;
290 if (!isswimming && not_walking)
301 accel = 3.0f * tmpRun;
304 if (!isswimming && not_walking)
311 tmpJoy = accel = tmpGoForward;
312 float tmpBack = tmpGoBackward;
314 tmpJoy = std::min(tmpJoy, 1.0f);
315 tmpBack = std::min(tmpBack, 1.0f);
317 if (tmpJoy > 0.0f || tmpRun > 0.0f)
320 accel = 3.0f * tmpRun;
344 else if (tmpBack > 0.0f)
380 if (anim_time_pos < 0.01f)
382 anim_time_pos = 0.01f;
410 std::string username;
413 username =
"~~ERROR getting username~~";
418 snprintf(msg_buf, 300,
419 "[RoR|Networking] ERROR on m_is_remote character (User: '%s', SourceID: %d, StreamID: %d): ",
433 memset(®, 0,
sizeof(reg));
435 strcpy(reg.
name,
"default");
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));
486 this->
SetAnimState(pos_msg->anim_name, pos_msg->anim_time);
494 this->
ReportError(
"Received command `DETACH`, but not currently attached to a vehicle. Ignoring command.");
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);
516 snprintf(err_buf, 100,
"Received invalid command: %d. Cannot process.", msg->command);
560 entity->getMesh()->_setBounds(aabb);
564 scenenode->attachObject(entity);
565 scenenode->setScale(0.02f, 0.02f, 0.02f);
566 scenenode->setVisible(
false);
569 MaterialPtr mat1 = MaterialManager::getSingleton().getByName(
"tracks/character");
583 Entity* ent =
static_cast<Ogre::Entity*
>(xc_scenenode->getAttachedObject(0));
584 xc_scenenode->detachAllObjects();
587 MaterialManager::getSingleton().unload(
"tracks/" + xc_instance_name);
592 xc_simbuf_prev = xc_simbuf;
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();
607 if (xc_simbuf.simbuf_actor_coupling != xc_simbuf_prev.simbuf_actor_coupling)
609 if (xc_simbuf.simbuf_actor_coupling !=
nullptr)
612 xc_scenenode->getAttachedObject(0)->setCastShadows(
false);
613 xc_scenenode->setVisible(xc_simbuf.simbuf_actor_coupling->GetGfxActor()->HasDriverSeatProp());
615 else if (xc_simbuf_prev.simbuf_actor_coupling !=
nullptr)
618 xc_scenenode->getAttachedObject(0)->setCastShadows(
true);
619 xc_scenenode->resetOrientation();
624 Ogre::Entity* entity =
static_cast<Ogre::Entity*
>(xc_scenenode->getAttachedObject(0));
625 if (xc_simbuf.simbuf_actor_coupling !=
nullptr)
628 GfxActor* gfx_actor = xc_simbuf.simbuf_actor_coupling->GetGfxActor();
634 entity->setVisible(
false);
644 if (entity->isVisible())
647 Ogre::Quaternion rot;
649 xc_scenenode->setOrientation(rot);
651 xc_scenenode->setPosition(pos + (rot * Vector3(0.f, -0.6f, 0.f)));
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);
663 if (xc_simbuf.simbuf_anim_name != xc_simbuf_prev.simbuf_anim_name)
666 AnimationStateIterator it = entity->getAllAnimationStates()->getAnimationStateIterator();
668 while (it.hasMoreElements())
670 AnimationState* as = it.getNext();
672 if (as->getAnimationName() == xc_simbuf.simbuf_anim_name)
674 as->setEnabled(
true);
676 as->addTime(xc_simbuf.simbuf_anim_time);
680 as->setEnabled(
false);
685 else if (xc_simbuf.simbuf_anim_name !=
"")
687 auto* as_cur = entity->getAnimationState(xc_simbuf.simbuf_anim_name);
688 as_cur->setTimePosition(xc_simbuf.simbuf_anim_time);
696 const String materialName =
"tracks/" + xc_instance_name;
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)
702 const auto& state = mat->getTechnique(0)->getPass(1)->getTextureUnitState(1);
704 state->setColourOperationEx(LBX_BLEND_CURRENT_ALPHA, LBS_MANUAL, LBS_CURRENT, color);
711 Ogre::Vector3 scene_pos = xc_scenenode->getPosition();
712 scene_pos.y += (1.9f + camDist / 100.0f);
Central state/object manager and communications hub.
#define CHARACTER_ANIM_NAME_LEN
float calculate_collision_depth(Vector3 pos)
Game state manager and message-queue provider.
This creates a billboarding object that displays a text.
int ar_net_source_id
Unique ID of remote player who spawned this actor.
Ogre::Real ar_hydro_dir_wheel_display
ActorPtrVec & GetActors()
const ActorPtr & GetActorByNetworkLinks(int source_id, int stream_id)
Ogre::SceneNode * GetCameraNode()
GfxCharacter * SetupGfx()
void setPosition(Ogre::Vector3 position)
ActorPtr m_actor_coupling
The vehicle or machine which the character occupies.
Ogre::Vector3 getPosition()
void setRotation(Ogre::Radian rotation)
float m_driving_anim_length
float m_character_v_speed
unsigned long m_net_last_update_time
Ogre::Vector3 m_prev_position
void receiveStreamData(unsigned int &type, int &source, unsigned int &streamid, char *buffer)
void SetActorCoupling(bool enabled, ActorPtr actor)
float m_net_last_anim_time
ActorPtr GetActorCoupling()
GfxCharacter * m_gfx_character
Ogre::Radian m_character_rotation
Ogre::Vector3 m_character_position
void move(Ogre::Vector3 offset)
void SetAnimState(std::string mode, float time=0)
void updateCharacterRotation()
std::string m_instance_name
float m_character_h_speed
Character(int source=-1, unsigned int streamid=0, std::string playerName="", int color_number=0, bool is_remote=true)
void ReportError(const char *detail)
bool collisionCorrect(Ogre::Vector3 *refpos, bool envokeScriptCallbacks=true)
const TerrainPtr & GetTerrain()
ActorManager * GetActorManager()
ActorSB & GetSimDataBuffer()
bool HasDriverSeatProp() const
void CalculateDriverPos(Ogre::Vector3 &out_pos, Ogre::Quaternion &out_rot)
void DrawNetLabel(Ogre::Vector3 pos, float cam_dist, std::string const &nick, int colornum)
void RemoveGfxCharacter(RoR::GfxCharacter *gfx_character)
Ogre::SceneManager * GetSceneManager()
Ogre::ColourValue GetPlayerColor(int color_num)
void AddLocalStream(RoRnet::StreamRegister *reg, int size)
void AddPacket(int streamid, int type, int len, const char *content)
float getHeightAt(float x, float z)
Collisions * GetCollisions()
float CalcWavesHeight(Vec3 pos, float timeshift_sec=0.f)
@ NETWORKED_OK
not simulated (remote) actor
@ NETWORKED_HIDDEN
not simulated, not updated (remote)
CVar * mp_hide_own_net_label
CVar * mp_hide_net_labels
InputEngine * GetInputEngine()
CameraManager * GetCameraManager()
GameContext * GetGameContext()
@ MSG2_STREAM_DATA_DISCARDABLE
stream data that is allowed to be discarded
@ MSG2_STREAM_DATA
stream data
ActorState simbuf_actor_state
Ogre::SceneNode * xc_scenenode
std::string xc_instance_name
void UpdateCharacterInScene()
void BufferSimulationData()
char anim_name[CHARACTER_ANIM_NAME_LEN]
< Sent from the client to server and vice versa, to broadcast a new stream
int32_t type
0 = Actor, 1 = Character, 3 = ChatSystem
char data[128]
data used for stream setup
int32_t origin_streamid
origin streamid
int32_t origin_sourceid
origin sourceid
int32_t status
initial stream status
char username[RORNET_MAX_USERNAME_LEN]
the nickname of the user (UTF-8)