From 721270c5a92954f2543250beaa3871dd95bd408c Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 14 Nov 2018 15:03:33 +0800 Subject: [PATCH 01/19] Fix #3566 --- src/guiengine/widgets/icon_button_widget.cpp | 5 ----- src/guiengine/widgets/icon_button_widget.hpp | 2 -- src/states_screens/online/networking_lobby.cpp | 4 ++-- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/guiengine/widgets/icon_button_widget.cpp b/src/guiengine/widgets/icon_button_widget.cpp index edd89f397..58a32264c 100644 --- a/src/guiengine/widgets/icon_button_widget.cpp +++ b/src/guiengine/widgets/icon_button_widget.cpp @@ -434,8 +434,3 @@ void IconButtonWidget::setVisible(bool visible) m_label->setVisible(visible); } -// ----------------------------------------------------------------------------- -void IconButtonWidget::setText(const wchar_t *s) -{ - m_label->setText(s); -} diff --git a/src/guiengine/widgets/icon_button_widget.hpp b/src/guiengine/widgets/icon_button_widget.hpp index 4c56ca55f..5580195f5 100644 --- a/src/guiengine/widgets/icon_button_widget.hpp +++ b/src/guiengine/widgets/icon_button_widget.hpp @@ -170,8 +170,6 @@ namespace GUIEngine Widget::elementRemoved(); m_label = NULL; } - // -------------------------------------------------------------------- - virtual void setText(const wchar_t *s) OVERRIDE; }; } diff --git a/src/states_screens/online/networking_lobby.cpp b/src/states_screens/online/networking_lobby.cpp index 7314b9533..95a6e0508 100644 --- a/src/states_screens/online/networking_lobby.cpp +++ b/src/states_screens/online/networking_lobby.cpp @@ -152,7 +152,7 @@ void NetworkingLobby::init() //I18N: In the networking lobby m_header->setText(_("Lobby"), false); m_server_info_height = GUIEngine::getFont()->getDimension(L"X").Height; - m_start_button->setText(_("Start race")); + m_start_button->setLabel(_("Start race")); m_start_button->setVisible(false); m_state = LS_CONNECTING; getWidget("chat")->setVisible(false); @@ -578,7 +578,7 @@ void NetworkingLobby::initAutoStartTimer(bool grand_prix_started, //I18N: In the networking lobby, ready button is to allow player to tell //server that he is ready for next game for owner less server - m_start_button->setText(_("Ready")); + m_start_button->setLabel(_("Ready")); m_has_auto_start_in_server = true; m_min_start_game_players = grand_prix_started ? 0 : min_players; m_start_timeout = start_timeout; From 5e711088bf3fadafaebdf913ce3568866af7371a Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 14 Nov 2018 16:01:36 +0800 Subject: [PATCH 02/19] Use better english as alayan suggested --- data/gui/screens/online/networking_lobby.stkgui | 12 ++++++------ src/states_screens/online/networking_lobby.cpp | 15 ++++++++------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/data/gui/screens/online/networking_lobby.stkgui b/data/gui/screens/online/networking_lobby.stkgui index be47888e2..9c068711d 100644 --- a/data/gui/screens/online/networking_lobby.stkgui +++ b/data/gui/screens/online/networking_lobby.stkgui @@ -15,14 +15,14 @@ -
- +
+ - +
-
diff --git a/src/states_screens/online/networking_lobby.cpp b/src/states_screens/online/networking_lobby.cpp index 95a6e0508..c7cd91fa1 100644 --- a/src/states_screens/online/networking_lobby.cpp +++ b/src/states_screens/online/networking_lobby.cpp @@ -250,7 +250,7 @@ void NetworkingLobby::onUpdate(float delta) //I18N: In the networking lobby, show when player is required to wait //before the current game finish core::stringw msg = _("Please wait for current game to end."); - m_timeout_message->setText(msg, true); + m_timeout_message->setText(msg, false); core::stringw total_msg; for (auto& string : m_server_info) { @@ -281,7 +281,7 @@ void NetworkingLobby::onUpdate(float delta) _P("Game will start if there is more than %d player.", "Game will start if there are more than %d players.", (int)(m_min_start_game_players - 1)); - m_timeout_message->setText(msg, true); + m_timeout_message->setText(msg, false); } if (m_cur_starting_timer != std::numeric_limits::max()) @@ -292,11 +292,12 @@ void NetworkingLobby::onUpdate(float delta) remain = 0; //I18N: In the networking lobby, display the starting timeout //for owner-less server to begin a game - core::stringw msg = _P("Starting after %d second " - "or everyone pressed 'Ready' button.", - "Starting after %d seconds " - "or everyone pressed 'Ready' button.", (int)remain); - m_timeout_message->setText(msg, true); + core::stringw msg = _P("Starting after %d second, " + "or once everyone has pressed the 'Ready' button.", + "Starting after %d seconds, " + "or once everyone has pressed the 'Ready' button.", + (int)remain); + m_timeout_message->setText(msg, false); } } else From 7b4a4e3727158018bc37a82139566c0b8339ac1c Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 14 Nov 2018 16:02:12 +0800 Subject: [PATCH 03/19] Fix connect to server message overshoot in text box --- src/states_screens/online/networking_lobby.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/states_screens/online/networking_lobby.cpp b/src/states_screens/online/networking_lobby.cpp index c7cd91fa1..8b05deec4 100644 --- a/src/states_screens/online/networking_lobby.cpp +++ b/src/states_screens/online/networking_lobby.cpp @@ -308,7 +308,7 @@ void NetworkingLobby::onUpdate(float delta) if (m_state == LS_ADD_PLAYERS) { m_text_bubble->setText(_("Everyone:\nPress the 'Select' button to " - "join the game"), true); + "join the game"), false); m_start_button->setVisible(false); m_exit_widget->setVisible(false); if (!GUIEngine::ModalDialog::isADialogActive()) @@ -334,7 +334,7 @@ void NetworkingLobby::onUpdate(float delta) connect_msg = StringUtils::loadingDots(_("Finding a quick play server")); } - m_text_bubble->setText(connect_msg, true); + m_text_bubble->setText(connect_msg, false); m_start_button->setVisible(false); } else From b91e018a18ec6d46963fd178d9d31e46711320e4 Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 14 Nov 2018 16:07:02 +0800 Subject: [PATCH 04/19] Use only y-axis for timed rotation --- src/karts/kart_rewinder.cpp | 6 +++--- src/karts/skidding.cpp | 6 +++--- src/physics/btKart.cpp | 8 ++++---- src/physics/btKart.hpp | 21 +++++++++++++-------- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/karts/kart_rewinder.cpp b/src/karts/kart_rewinder.cpp index dd1eca38a..caec91096 100755 --- a/src/karts/kart_rewinder.cpp +++ b/src/karts/kart_rewinder.cpp @@ -155,7 +155,7 @@ BareNetworkString* KartRewinder::saveState(std::vector* ru) buffer->add(body->getLinearVelocity()); buffer->add(body->getAngularVelocity()); buffer->addUInt16(m_vehicle->getTimedRotationTicks()); - buffer->add(m_vehicle->getTimedRotation()); + buffer->addFloat(m_vehicle->getTimedRotation()); // For collision rewind buffer->addUInt16(m_bounce_back_ticks); @@ -262,10 +262,10 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count) } uint16_t time_rot = buffer->getUInt16(); + float timed_rotation_y = buffer->getFloat(); // Set timed rotation divides by time_rot m_vehicle->setTimedRotation(time_rot, - stk_config->ticks2Time(time_rot) - * buffer->getVec3()); + stk_config->ticks2Time(time_rot) * timed_rotation_y); // Collision rewind m_bounce_back_ticks = buffer->getUInt16(); diff --git a/src/karts/skidding.cpp b/src/karts/skidding.cpp index 97fc861ec..9c0df0c2f 100644 --- a/src/karts/skidding.cpp +++ b/src/karts/skidding.cpp @@ -87,7 +87,7 @@ void Skidding::reset() btVector3 rot(0, 0, 0); // Only access the vehicle if the kart is not a ghost if (!m_kart->isGhostKart()) - m_kart->getVehicle()->setTimedRotation(0, rot); + m_kart->getVehicle()->setTimedRotation(0, 0); } // reset // ---------------------------------------------------------------------------- @@ -535,9 +535,9 @@ void Skidding::update(int ticks, bool is_on_ground, float t = std::min(skid_time_float, kp->getSkidVisualTime()); t = std::min(t, kp->getSkidRevertVisualTime()); - btVector3 rot(0, m_visual_rotation * kp->getSkidPostSkidRotateFactor(), 0); m_kart->getVehicle()->setTimedRotation( - (uint16_t)stk_config->time2Ticks(t), rot); + (uint16_t)stk_config->time2Ticks(t), + m_visual_rotation * kp->getSkidPostSkidRotateFactor()); // skid_time is used to count backwards for the GFX m_skid_time = stk_config->time2Ticks(t); if(bonus_time>0) diff --git a/src/physics/btKart.cpp b/src/physics/btKart.cpp index 9c6d51ad6..b76a511f5 100644 --- a/src/physics/btKart.cpp +++ b/src/physics/btKart.cpp @@ -121,7 +121,7 @@ void btKart::reset() m_num_wheels_on_ground = 0; m_additional_impulse = btVector3(0,0,0); m_ticks_additional_impulse = 0; - m_additional_rotation = btVector3(0,0,0); + m_additional_rotation = 0; m_ticks_additional_rotation = 0; m_max_speed = -1.0f; m_min_speed = 0.0f; @@ -522,9 +522,9 @@ void btKart::updateVehicle( btScalar step ) btTransform &t = m_chassisBody->getWorldTransform(); // We have fixed timestep float dt = stk_config->ticks2Time(1); - btQuaternion add_rot(m_additional_rotation.getY()*dt, - m_additional_rotation.getX()*dt, - m_additional_rotation.getZ()*dt); + btQuaternion add_rot(m_additional_rotation * dt, + 0.0f, + 0.0f); t.setRotation(t.getRotation()*add_rot); m_chassisBody->setWorldTransform(t); // Also apply the rotation to the interpolated world transform. diff --git a/src/physics/btKart.hpp b/src/physics/btKart.hpp index ff2396946..acc8d6a9a 100644 --- a/src/physics/btKart.hpp +++ b/src/physics/btKart.hpp @@ -83,8 +83,8 @@ private: /** The time the additional impulse should be applied. */ uint16_t m_ticks_additional_impulse; - /** Additional rotation that is applied over a certain amount of time. */ - btVector3 m_additional_rotation; + /** Additional rotation in y-axis that is applied over a certain amount of time. */ + float m_additional_rotation; /** Duration over which the additional rotation is applied. */ uint16_t m_ticks_additional_rotation; @@ -236,21 +236,26 @@ public: { return m_ticks_additional_impulse; } // ------------------------------------------------------------------------ const btVector3& getAdditionalImpulse() const - { return m_additional_impulse; } + { return m_additional_impulse; } // ------------------------------------------------------------------------ /** Sets a rotation that is applied over a certain amount of time (to avoid * a too rapid changes in the kart). * \param t Ticks for the rotation to be applied. - * \param torque The rotation to apply. */ - void setTimedRotation(uint16_t t, const btVector3 &rot) + * \param rot_in_y_axis The rotation in y-axis to apply. */ + void setTimedRotation(uint16_t t, float rot_in_y_axis) { - if(t>0) m_additional_rotation = rot / (stk_config->ticks2Time(t)); + if (t > 0) + { + m_additional_rotation = + rot_in_y_axis / (stk_config->ticks2Time(t)); + } m_ticks_additional_rotation = t; } // setTimedTorque // ------------------------------------------------------------------------ - const btVector3& getTimedRotation() const { return m_additional_rotation; } + float getTimedRotation() const { return m_additional_rotation; } // ------------------------------------------------------------------------ - uint16_t getTimedRotationTicks() const { return m_ticks_additional_rotation; } + uint16_t getTimedRotationTicks() const + { return m_ticks_additional_rotation; } // ------------------------------------------------------------------------ /** Sets the maximum speed for this kart. */ void setMaxSpeed(float new_max_speed) From 12c3a303857ed18f2c75e8f899d6af6f17a889d2 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 15 Nov 2018 09:06:41 +1100 Subject: [PATCH 05/19] Also transfer the normal for an item from server to client. --- src/items/item.cpp | 15 +++++--- src/items/item.hpp | 27 +++++++++++--- src/items/item_event_info.cpp | 6 +++- src/items/item_event_info.hpp | 14 ++++++-- src/items/item_manager.cpp | 57 +++++++++++++++--------------- src/items/item_manager.hpp | 4 ++- src/items/network_item_manager.cpp | 17 +++++---- src/items/network_item_manager.hpp | 6 ++-- 8 files changed, 97 insertions(+), 49 deletions(-) mode change 100644 => 100755 src/items/network_item_manager.cpp diff --git a/src/items/item.cpp b/src/items/item.cpp index 6808222b4..770b141ba 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -74,10 +74,13 @@ void ItemState::setDisappearCounter() // ----------------------------------------------------------------------- /** Initialises an item. * \param type Type for this item. + * \param xyz The position for this item. + * \param normal The normal for this item. */ -void ItemState::initItem(ItemType type, const Vec3& xyz) +void ItemState::initItem(ItemType type, const Vec3& xyz, const Vec3& normal) { m_xyz = xyz; + m_normal = normal; m_original_type = ITEM_NONE; m_ticks_till_return = 0; setDisappearCounter(); @@ -156,7 +159,7 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal, m_was_available_previously = true; m_distance_2 = 1.2f; - initItem(type, xyz); + initItem(type, xyz, normal); m_graphical_type = type; m_original_rotation = shortestArcQuat(Vec3(0, 1, 0), normal); m_listener = NULL; @@ -206,7 +209,7 @@ Item::Item(const Vec3& xyz, float distance, TriggerItemListener* trigger) : ItemState(ITEM_TRIGGER) { m_distance_2 = distance*distance; - initItem(ITEM_TRIGGER, xyz); + initItem(ITEM_TRIGGER, xyz, /*normal not required*/Vec3(0,0,0)); m_graphical_type = ITEM_TRIGGER; m_original_rotation = btQuaternion(0, 0, 0, 1); m_node = NULL; @@ -218,10 +221,12 @@ Item::Item(const Vec3& xyz, float distance, TriggerItemListener* trigger) /** Initialises the item. Note that m_distance_2 must be defined before calling * this function, since it pre-computes some values based on this. * \param type Type of the item. + * \param xyz Position of this item. + * \param normal Normal for this item. */ -void Item::initItem(ItemType type, const Vec3 &xyz) +void Item::initItem(ItemType type, const Vec3 &xyz, const Vec3&normal) { - ItemState::initItem(type, xyz); + ItemState::initItem(type, xyz, normal); // Now determine in which quad this item is, and its distance // from the center within this quad. m_graph_node = Graph::UNKNOWN_SECTOR; diff --git a/src/items/item.hpp b/src/items/item.hpp index 857250651..5be813fea 100644 --- a/src/items/item.hpp +++ b/src/items/item.hpp @@ -119,10 +119,17 @@ private: * will always reappear after a while. */ int m_used_up_counter; - /** The original position - saves calls to m_node->getPosition() - * and then converting this value to a Vec3. */ + /** The position of this ItemState. */ Vec3 m_xyz; + /** The original rotation of the item. While this is technically a visual + * only value (atm, it could be used for collision detection), it is + * required to make sure a client can display items with the right normal + * (in case that a client would get a different (or no) normal from a + * raycast). + */ + Vec3 m_normal; + /** The 'owner' of the item, i.e. the kart that dropped this item. * Is NULL if the item is part of the track. */ const AbstractKart *m_previous_owner; @@ -154,7 +161,7 @@ protected: public: ItemState(ItemType type, const AbstractKart *owner=NULL, int id = -1); - void initItem(ItemType type, const Vec3& xyz); + void initItem(ItemType type, const Vec3& xyz, const Vec3& normal); void update(int ticks); void setDisappearCounter(); virtual void collected(const AbstractKart *kart); @@ -305,6 +312,12 @@ public: // ------------------------------------------------------------------------ /** Returns the XYZ position of the item. */ const Vec3& getXYZ() const { return m_xyz; } + // ------------------------------------------------------------------------ + /** Returns the normal of the ItemState. */ + const Vec3 getNormal() const + { + return m_normal; + } }; // class ItemState // ============================================================================ @@ -350,7 +363,7 @@ private: * would not be collected. Used by the AI to avoid items. */ Vec3 *m_avoidance_points[2]; - void initItem(ItemType type, const Vec3 &xyz); + void initItem(ItemType type, const Vec3 &xyz, const Vec3 &normal); void setMesh(scene::IMesh* mesh, scene::IMesh* lowres_mesh); void handleNewMesh(ItemType type); @@ -432,6 +445,12 @@ public: return m_avoidance_points[1]; } // getAvoidancePoint + // ------------------------------------------------------------------------ + /** Returns the normal of the item. */ + const Vec3 getNormal() const + { + return quatRotate(m_original_rotation, Vec3(0,1,0)); + } // ------------------------------------------------------------------------ scene::ISceneNode *getSceneNode() { diff --git a/src/items/item_event_info.cpp b/src/items/item_event_info.cpp index 4748d0408..761574cf5 100644 --- a/src/items/item_event_info.cpp +++ b/src/items/item_event_info.cpp @@ -43,7 +43,8 @@ ItemEventInfo::ItemEventInfo(BareNetworkString *buffer, int *count) if (m_type == IEI_NEW) { m_xyz = buffer->getVec3(); - *count -= 12; + m_normal = buffer->getVec3(); + *count -= 24; } else // IEI_COLLECT { @@ -71,7 +72,10 @@ void ItemEventInfo::saveState(BareNetworkString *buffer) // Only new item and collecting items need the index and kart id: buffer->addUInt8(m_kart_id).addUInt16(m_index); if (m_type == IEI_NEW) + { buffer->add(m_xyz); + buffer->add(m_normal); + } else if (m_type == IEI_COLLECT) buffer->addUInt16(m_ticks_till_return); } diff --git a/src/items/item_event_info.hpp b/src/items/item_event_info.hpp index 09f76feb0..00ed5462a 100644 --- a/src/items/item_event_info.hpp +++ b/src/items/item_event_info.hpp @@ -52,6 +52,9 @@ private: /** In case of new items the position of the new item. */ Vec3 m_xyz; + /** The normal of an item. */ + Vec3 m_normal; + /** Ticks for the item to return, atm used by collecting banana * with bomb to delay the return for banana. */ int16_t m_ticks_till_return; @@ -76,9 +79,9 @@ public: * need to encode the new item type. */ ItemEventInfo(int ticks, ItemState::ItemType type, int index, - int kart_id, const Vec3 &xyz) + int kart_id, const Vec3 &xyz, const Vec3 &normal) : m_ticks(ticks), m_index(index), m_kart_id(kart_id), m_xyz(xyz), - m_ticks_till_return(0) + m_normal(normal), m_ticks_till_return(0) { m_type = IEI_NEW; } // ItemEventInfo(new item) @@ -125,6 +128,13 @@ public: return m_xyz; } // getXYZ // -------------------------------------------------------------------- + /** Returns the normal of a new item only. */ + const Vec3& getNormal() const + { + assert(isNewItem()); + return m_normal; + } // getNormal + // -------------------------------------------------------------------- /** Returns the ticks till return, used only by collection events. */ int getTicksTillReturn() const { return m_ticks_till_return; } // -------------------------------------------------------------------- diff --git a/src/items/item_manager.cpp b/src/items/item_manager.cpp index a62a06ebd..ff49f9fe4 100644 --- a/src/items/item_manager.cpp +++ b/src/items/item_manager.cpp @@ -257,42 +257,43 @@ unsigned int ItemManager::insertItem(Item *item) * bubblegum). * \param type Type of the item. * \param kart The kart that drops the new item. - * \param xyz Can be used to overwrite the item location (used in networking). + * \param server_xyz Can be used to overwrite the item location. + * \param server_normal The normal as seen on the server. */ Item* ItemManager::dropNewItem(ItemState::ItemType type, - const AbstractKart *kart, const Vec3 *xyz) + const AbstractKart *kart, + const Vec3 *server_xyz, + const Vec3 *server_normal) { - Vec3 hit_point; - Vec3 normal; + if(NetworkConfig::get()->isClient() && !server_xyz) return NULL; + Vec3 normal, pos; const Material* material_hit; - Vec3 pos = xyz ? *xyz : kart->getXYZ(); - Vec3 to = pos + kart->getTrans().getBasis() * Vec3(0, -10000, 0); - Track::getCurrentTrack()->getTriangleMesh().castRay(pos, to, - &hit_point, - &material_hit, - &normal); - - // We will get no material if the kart is 'over nothing' when dropping - // the bubble gum. In most cases this means that the item does not need - // to be created (and we just return NULL). Only exception: if the server - // has sent a 'new item' event (which means its raycast found terrain), - // but the client does not have found a terrain (e.g. differences in - // position or more likely floating point differences). In this case, we - // must use the server position. In this and only this case xyz is not - // NULL (and then contains the server's position for the item). - if (!material_hit && !xyz) return NULL; - - if (!material_hit) + if (!server_xyz) { - // We are on a client which has received a new item event. Still - // create this item - normal.setValue(0, 1, 0); // Arbitrary, we don't have a normal - pos = *xyz; + // We are doing a new drop locally, i.e. not based on + // server data. So we need a raycast to find the correct + // location and normal of the item: + pos = server_xyz ? *server_xyz : kart->getXYZ(); + Vec3 to = pos + kart->getTrans().getBasis() * Vec3(0, -10000, 0); + Vec3 hit_point; + Track::getCurrentTrack()->getTriangleMesh().castRay(pos, to, + &hit_point, + &material_hit, + &normal); + + // We will get no material if the kart is 'over nothing' when dropping + // the bubble gum. In most cases this means that the item does not need + // to be created (and we just return NULL). + if (!material_hit) return NULL; + normal.normalize(); + pos = hit_point + kart->getTrans().getBasis() * Vec3(0, -0.05f, 0); } else { - normal.normalize(); - pos = hit_point + kart->getTrans().getBasis() * Vec3(0, -0.05f, 0); + // We are on a client which has received a new item event from the + // server. So use the server's data for the new item: + normal = *server_normal; + pos = *server_xyz; } ItemState::ItemType mesh_type = type; diff --git a/src/items/item_manager.hpp b/src/items/item_manager.hpp index f9f6f831d..b3896b256 100644 --- a/src/items/item_manager.hpp +++ b/src/items/item_manager.hpp @@ -133,7 +133,9 @@ public: virtual Item* placeItem (ItemState::ItemType type, const Vec3& xyz, const Vec3 &normal); virtual Item* dropNewItem (ItemState::ItemType type, - const AbstractKart* parent, const Vec3 *xyz=NULL); + const AbstractKart* parent, + const Vec3 *server_xyz = NULL, + const Vec3 *normal = NULL); virtual Item* placeTrigger (const Vec3& xyz, float distance, TriggerItemListener* listener); void update (int ticks); diff --git a/src/items/network_item_manager.cpp b/src/items/network_item_manager.cpp old mode 100644 new mode 100755 index 2afeec91c..9f1b60005 --- a/src/items/network_item_manager.cpp +++ b/src/items/network_item_manager.cpp @@ -148,23 +148,29 @@ void NetworkItemManager::switchItems() * \param type Type of the item. * \param kart In case of a dropped item used to avoid that a kart * is affected by its own items. + * \param server_xyz In case of rewind the server's position of this item. + * \param server_normal In case of rewind the server's normal of this item. */ Item* NetworkItemManager::dropNewItem(ItemState::ItemType type, - const AbstractKart *kart, const Vec3 *xyz) + const AbstractKart *kart, + const Vec3 *server_xyz, + const Vec3 *server_normal) { - Item *item = ItemManager::dropNewItem(type, kart, xyz); + Item *item = ItemManager::dropNewItem(type, kart, server_xyz, server_normal); if(!item) return NULL; // Nothing else to do for client if (NetworkConfig::get()->isClient()) return item; + assert(!server_xyz); // Server: store the data for this event: m_item_events.lock(); m_item_events.getData().emplace_back(World::getWorld()->getTicksSinceStart(), type, item->getItemId(), kart->getWorldKartId(), - xyz ? *xyz : kart->getXYZ() ); + item->getXYZ(), + item->getNormal()); m_item_events.unlock(); return item; } // dropNewItem @@ -409,7 +415,7 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count) AbstractKart *kart = world->getKart(iei.getKartId()); ItemState *is = new ItemState(iei.getNewItemType(), kart, iei.getIndex() ); - is->initItem(iei.getNewItemType(), iei.getXYZ()); + is->initItem(iei.getNewItemType(), iei.getXYZ(), iei.getNormal()); if (m_switch_ticks >= 0) { ItemState::ItemType new_type = m_switch_to[is->getType()]; @@ -490,9 +496,8 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count) { // A new item was dropped according to the server that is not // yet part of the current state --> create new item - Vec3 xyz = is->getXYZ(); Item *item_new = dropNewItem(is->getType(), is->getPreviousOwner(), - &xyz); + &(is->getXYZ()), &(is->getNormal()) ); if (i != item_new->getItemId()) { // The newly created item on the client has been given a diff --git a/src/items/network_item_manager.hpp b/src/items/network_item_manager.hpp index 342285756..a49b5b1db 100644 --- a/src/items/network_item_manager.hpp +++ b/src/items/network_item_manager.hpp @@ -80,8 +80,10 @@ public: int ticks) OVERRIDE; virtual void collectedItem(ItemState *item, AbstractKart *kart) OVERRIDE; virtual void switchItems() OVERRIDE; - virtual Item* dropNewItem(ItemState::ItemType type, const AbstractKart *kart, - const Vec3 *xyz=NULL) OVERRIDE; + virtual Item* dropNewItem(ItemState::ItemType type, + const AbstractKart *kart, + const Vec3 *server_xyz = NULL, + const Vec3 *server_normal = NULL) OVERRIDE; virtual BareNetworkString* saveState(std::vector* ru) OVERRIDE; virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE; From c2481ba68ceb3b524e8cbd8a9697f761eda10802 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 15 Nov 2018 11:59:06 +1100 Subject: [PATCH 06/19] Fixed compilatione error. --- src/items/network_item_manager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) mode change 100755 => 100644 src/items/network_item_manager.cpp diff --git a/src/items/network_item_manager.cpp b/src/items/network_item_manager.cpp old mode 100755 new mode 100644 index 9f1b60005..1e986694d --- a/src/items/network_item_manager.cpp +++ b/src/items/network_item_manager.cpp @@ -496,8 +496,10 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count) { // A new item was dropped according to the server that is not // yet part of the current state --> create new item + Vec3 xyz = is->getXYZ(); + Vec3 normal = is->getNormal(); Item *item_new = dropNewItem(is->getType(), is->getPreviousOwner(), - &(is->getXYZ()), &(is->getNormal()) ); + &xyz, &normal ); if (i != item_new->getItemId()) { // The newly created item on the client has been given a From 2da880859299c03a302e9e2dba8e3bc499fa1287 Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 16 Nov 2018 01:38:46 +0800 Subject: [PATCH 07/19] Remove unneeded mask --- src/items/flyable.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/items/flyable.cpp b/src/items/flyable.cpp index 5591577a3..61fd226b4 100644 --- a/src/items/flyable.cpp +++ b/src/items/flyable.cpp @@ -653,9 +653,7 @@ void Flyable::restoreState(BareNetworkString *buffer, int count) m_body->setInterpolationAngularVelocity(av); setTrans(t); } - uint16_t hit_and_ticks = buffer->getUInt16(); - // Next network version remove ~(1 << 15) - m_ticks_since_thrown = hit_and_ticks & ~(1 << 15); + m_ticks_since_thrown = buffer->getUInt16(); m_has_server_state = true; } // restoreState From 264b79ef0d305558b548a53b6066196c584b6061 Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 16 Nov 2018 12:48:53 +0800 Subject: [PATCH 08/19] Replace exit button with server configuration for future usage --- data/gui/screens/online/networking_lobby.stkgui | 4 ++-- src/states_screens/online/networking_lobby.cpp | 12 +----------- src/states_screens/online/networking_lobby.hpp | 1 - 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/data/gui/screens/online/networking_lobby.stkgui b/data/gui/screens/online/networking_lobby.stkgui index 9c068711d..fd63d61d5 100644 --- a/data/gui/screens/online/networking_lobby.stkgui +++ b/data/gui/screens/online/networking_lobby.stkgui @@ -28,8 +28,8 @@ - +
diff --git a/src/states_screens/online/networking_lobby.cpp b/src/states_screens/online/networking_lobby.cpp index 8b05deec4..fddf4726c 100644 --- a/src/states_screens/online/networking_lobby.cpp +++ b/src/states_screens/online/networking_lobby.cpp @@ -70,7 +70,6 @@ NetworkingLobby::NetworkingLobby() : Screen("online/networking_lobby.stkgui") m_header = NULL; m_text_bubble = NULL; m_timeout_message = NULL; - m_exit_widget = NULL; m_start_button = NULL; m_player_list = NULL; m_chat_box = NULL; @@ -106,9 +105,6 @@ void NetworkingLobby::loadedFromFile() m_player_list = getWidget("players"); assert(m_player_list!= NULL); - m_exit_widget = getWidget("exit"); - assert(m_exit_widget != NULL); - m_icon_bank = new irr::gui::STKModifiedSpriteBank(GUIEngine::getGUIEnv()); video::ITexture* icon_1 = irr_driver->getTexture (file_manager->getAsset(FileManager::GUI_ICON, "crown.png")); @@ -140,6 +136,7 @@ void NetworkingLobby::init() { Screen::init(); + getWidget("config")->setVisible(false); m_player_names.clear(); m_allow_change_team = false; m_has_auto_start_in_server = false; @@ -245,7 +242,6 @@ void NetworkingLobby::onUpdate(float delta) if (cl && cl->isWaitingForGame()) { m_start_button->setVisible(false); - m_exit_widget->setVisible(true); m_timeout_message->setVisible(true); //I18N: In the networking lobby, show when player is required to wait //before the current game finish @@ -310,7 +306,6 @@ void NetworkingLobby::onUpdate(float delta) m_text_bubble->setText(_("Everyone:\nPress the 'Select' button to " "join the game"), false); m_start_button->setVisible(false); - m_exit_widget->setVisible(false); if (!GUIEngine::ModalDialog::isADialogActive()) { input_manager->getDeviceManager()->setAssignMode(DETECT_NEW); @@ -320,7 +315,6 @@ void NetworkingLobby::onUpdate(float delta) } m_start_button->setVisible(false); - m_exit_widget->setVisible(true); if (!cl || !cl->isLobbyReady()) { core::stringw connect_msg; @@ -437,10 +431,6 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, sendChat(m_chat_box->getText()); m_chat_box->setText(""); } // send chat message - else if (name == m_exit_widget->m_properties[PROP_ID]) - { - StateManager::get()->escapePressed(); - } else if (name == m_start_button->m_properties[PROP_ID]) { // Send a message to the server to start diff --git a/src/states_screens/online/networking_lobby.hpp b/src/states_screens/online/networking_lobby.hpp index d534d4d7f..468cc1a07 100644 --- a/src/states_screens/online/networking_lobby.hpp +++ b/src/states_screens/online/networking_lobby.hpp @@ -82,7 +82,6 @@ private: GUIEngine::LabelWidget* m_header; GUIEngine::LabelWidget* m_text_bubble; GUIEngine::LabelWidget* m_timeout_message; - GUIEngine::IconButtonWidget* m_exit_widget; GUIEngine::IconButtonWidget* m_start_button; GUIEngine::ListWidget* m_player_list; GUIEngine::TextBoxWidget* m_chat_box; From eb8b68dcb6d1caff5c18ebf09c97a564312f3971 Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 16 Nov 2018 19:46:48 +0800 Subject: [PATCH 09/19] Allow text box widget to process left / right events --- src/guiengine/widgets/CGUIEditBox.hpp | 3 ++- src/guiengine/widgets/text_box_widget.cpp | 19 +++++++++++++++++++ src/guiengine/widgets/text_box_widget.hpp | 3 +++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/guiengine/widgets/CGUIEditBox.hpp b/src/guiengine/widgets/CGUIEditBox.hpp index 0db5f3731..cf3a0dd56 100644 --- a/src/guiengine/widgets/CGUIEditBox.hpp +++ b/src/guiengine/widgets/CGUIEditBox.hpp @@ -120,7 +120,8 @@ using namespace gui; virtual void setDrawBackground(bool) { } void openScreenKeyboard(); - + s32 getCursorPosInBox() const { return CursorPos; } + s32 getTextCount() const { return (s32)Text.size(); } protected: //! Breaks the single text line. void breakText(); diff --git a/src/guiengine/widgets/text_box_widget.cpp b/src/guiengine/widgets/text_box_widget.cpp index 57d3d7185..e6d7712a9 100644 --- a/src/guiengine/widgets/text_box_widget.cpp +++ b/src/guiengine/widgets/text_box_widget.cpp @@ -209,3 +209,22 @@ EventPropagation TextBoxWidget::onActivationInput(const int playerID) // event to avoid breaking something return EVENT_BLOCK; } + +// ----------------------------------------------------------------------------- +EventPropagation TextBoxWidget::rightPressed(const int playerID) +{ + if (((MyCGUIEditBox*)m_element)->getTextCount() == + ((MyCGUIEditBox*)m_element)->getCursorPosInBox()) + return EVENT_BLOCK; + + return EVENT_LET; +} // rightPressed + +// ----------------------------------------------------------------------------- +EventPropagation TextBoxWidget::leftPressed (const int playerID) +{ + if (((MyCGUIEditBox*)m_element)->getCursorPosInBox() == 0) + return EVENT_BLOCK; + + return EVENT_LET; +} // leftPressed diff --git a/src/guiengine/widgets/text_box_widget.hpp b/src/guiengine/widgets/text_box_widget.hpp index 54d462387..db53359b7 100644 --- a/src/guiengine/widgets/text_box_widget.hpp +++ b/src/guiengine/widgets/text_box_widget.hpp @@ -77,6 +77,9 @@ namespace GUIEngine virtual void setActive(bool active=true); virtual EventPropagation onActivationInput(const int playerID); + virtual EventPropagation rightPressed(const int playerID); + virtual EventPropagation leftPressed (const int playerID); + }; } From f94e226e226ef160500708167144ec54af8794a7 Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 16 Nov 2018 20:56:21 +0800 Subject: [PATCH 10/19] Add ready status to player icon --- src/network/protocols/client_lobby.cpp | 3 +++ src/network/protocols/server_lobby.cpp | 12 +++++++++++- src/states_screens/online/networking_lobby.cpp | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index 4a125d010..66ec4ec4f 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -697,6 +697,9 @@ void ClientLobby::updatePlayerList(Event* event) if (d == PLAYER_DIFFICULTY_HANDICAP) std::get<3>(pl) = _("%s (handicapped)", std::get<3>(pl)); std::get<5>(pl) = (KartTeam)data.getUInt8(); + bool ready = data.getUInt8() == 1; + if (ready) + std::get<4>(pl) = 4; players.push_back(pl); } diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 4d3310d18..da2be275c 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -460,6 +460,8 @@ void ServerLobby::asynchronousUpdate() !m_game_setup->isGrandPrixStarted()) { resetPeersReady(); + if (m_timeout.load() != std::numeric_limits::max()) + updatePlayerList(); m_timeout.store(std::numeric_limits::max()); } if (m_timeout.load() < (int64_t)StkTime::getRealTimeMs() || @@ -833,7 +835,9 @@ void ServerLobby::startSelection(const Event *event) } if (ServerConfig::m_owner_less) { - m_peers_ready.at(event->getPeerSP()) = true; + m_peers_ready.at(event->getPeerSP()) = + !m_peers_ready.at(event->getPeerSP()); + updatePlayerList(); return; } if (event->getPeerSP() != m_server_owner.lock()) @@ -1744,6 +1748,11 @@ void ServerLobby::updatePlayerList(bool update_when_reset_server) pl->addUInt8(profile->getTeam()); else pl->addUInt8(KART_TEAM_NONE); + std::shared_ptr p = profile->getPeer(); + uint8_t ready = (!game_started && + m_peers_ready.find(p) != m_peers_ready.end() && + m_peers_ready.at(p)) ? 1 : 0; + pl->addUInt8(ready); } // Don't send this message to in-game players @@ -2445,6 +2454,7 @@ void ServerLobby::addWaitingPlayersToGame() void ServerLobby::resetServer() { addWaitingPlayersToGame(); + resetPeersReady(); m_state = NetworkConfig::get()->isLAN() ? WAITING_FOR_START_GAME : REGISTER_SELF_ADDRESS; updatePlayerList(true/*update_when_reset_server*/); diff --git a/src/states_screens/online/networking_lobby.cpp b/src/states_screens/online/networking_lobby.cpp index fddf4726c..29c7afd38 100644 --- a/src/states_screens/online/networking_lobby.cpp +++ b/src/states_screens/online/networking_lobby.cpp @@ -114,10 +114,13 @@ void NetworkingLobby::loadedFromFile() (file_manager->getAsset(FileManager::GUI_ICON, "main_help.png")); video::ITexture* icon_4 = irr_driver->getTexture (file_manager->getAsset(FileManager::GUI_ICON, "hourglass.png")); + video::ITexture* icon_5 = irr_driver->getTexture + (file_manager->getAsset(FileManager::GUI_ICON, "green_check.png")); m_icon_bank->addTextureAsSprite(icon_1); m_icon_bank->addTextureAsSprite(icon_2); m_icon_bank->addTextureAsSprite(icon_3); m_icon_bank->addTextureAsSprite(icon_4); + m_icon_bank->addTextureAsSprite(icon_5); const int screen_width = irr_driver->getFrameSize().Width; m_icon_bank->setScale(screen_width > 1280 ? 0.4f : 0.25f); } // loadedFromFile From eb0000f8e048007c807f16591639ee1af43d9301 Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 16 Nov 2018 22:58:27 +0800 Subject: [PATCH 11/19] Move arena / soccer scores (limit) to have their own place --- src/states_screens/race_gui.cpp | 128 ++++++++++++-------------------- src/states_screens/race_gui.hpp | 4 +- 2 files changed, 51 insertions(+), 81 deletions(-) diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index 1f774b5c2..c5dc8c0cb 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -197,6 +197,7 @@ RaceGUI::RaceGUI() m_blue_flag = irr_driver->getTexture(FileManager::GUI_ICON, "blue_flag.png"); m_soccer_ball = irr_driver->getTexture(FileManager::GUI_ICON, "soccer_ball_normal.png"); m_heart_icon = irr_driver->getTexture(FileManager::GUI_ICON, "heart.png"); + m_champion = irr_driver->getTexture(FileManager::GUI_ICON, "gp_new.png"); } // RaceGUI //----------------------------------------------------------------------------- @@ -307,8 +308,6 @@ void RaceGUI::renderGlobal(float dt) drawGlobalPlayerIcons(0); } } - if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER) - drawScores(); #endif } // renderGlobal @@ -354,55 +353,6 @@ void RaceGUI::renderPlayerView(const Camera *camera, float dt) drawLap(kart, viewport, scaling); } // renderPlayerView - -//----------------------------------------------------------------------------- -/** Shows the current soccer result. - */ -void RaceGUI::drawScores() -{ -#ifndef SERVER_ONLY - SoccerWorld* sw = dynamic_cast(World::getWorld()); - int offset_y = 5; - int offset_x = 5; - gui::ScalableFont* font = GUIEngine::getTitleFont(); - static video::SColor color = video::SColor(255,255,255,255); - - //Draw two teams score - irr::video::ITexture *team_icon = m_red_team; - - for(unsigned int i=0; i<2; i++) - { - core::recti position(offset_x, offset_y, - offset_x + 2*m_minimap_player_size, offset_y + 2*m_minimap_player_size); - - core::stringw score = StringUtils::toWString(sw->getScore((KartTeam)i)); - int string_height = - GUIEngine::getFont()->getDimension(score.c_str()).Height; - core::recti pos(position.UpperLeftCorner.X + 5, - position.LowerRightCorner.Y + offset_y, - position.LowerRightCorner.X, - position.LowerRightCorner.Y + string_height); - - font->setBlackBorder(true); - font->draw(score.c_str(),pos,color); - font->setBlackBorder(false); - - if (i == 1) - { - team_icon = m_blue_team; - } - core::rect indicator_pos(offset_x, offset_y, - offset_x + (int)(m_minimap_player_size*2), - offset_y + (int)(m_minimap_player_size*2)); - core::rect source_rect(core::position2d(0,0), - team_icon->getSize()); - draw2DImage(team_icon,indicator_pos,source_rect, - NULL,NULL,true); - offset_x += position.LowerRightCorner.X + 30; - } -#endif -} // drawScores - //----------------------------------------------------------------------------- /** Displays the racing time on the screen. */ @@ -843,29 +793,6 @@ void RaceGUI::drawRank(const AbstractKart *kart, int meter_height, float dt) { static video::SColor color = video::SColor(255, 255, 255, 255); - // Draw hit or capture limit in network game - if ((race_manager->getMajorMode() == RaceManager::MAJOR_MODE_FREE_FOR_ALL || - race_manager->getMajorMode() == RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG) && - race_manager->getHitCaptureLimit() != std::numeric_limits::max()) - { - gui::ScalableFont* font = GUIEngine::getHighresDigitFont(); - font->setScale(min_ratio * 1.0f); - font->setShadow(video::SColor(255, 128, 0, 0)); - std::ostringstream oss; - oss << race_manager->getHitCaptureLimit(); - - core::recti pos; - pos.LowerRightCorner = core::vector2di(int(offset.X + 0.64f*meter_width), - int(offset.Y - 0.49f*meter_height)); - pos.UpperLeftCorner = core::vector2di(int(offset.X + 0.64f*meter_width), - int(offset.Y - 0.49f*meter_height)); - - font->setBlackBorder(true); - font->draw(oss.str().c_str(), pos, color, true, true); - font->setBlackBorder(false); - font->setScale(1.0f); - return; - } // Draw rank WorldWithRank *world = dynamic_cast(World::getWorld()); @@ -1223,14 +1150,50 @@ void RaceGUI::drawLap(const AbstractKart* kart, - m_lap_width - 10; pos.LowerRightCorner.X = viewport.LowerRightCorner.X; - // Draw CTF scores with red score - blue score + // Draw CTF / soccer scores with red score - blue score (score limit) CaptureTheFlag* ctf = dynamic_cast(World::getWorld()); - if (ctf) + SoccerWorld* sw = dynamic_cast(World::getWorld()); + FreeForAll* ffa = dynamic_cast(World::getWorld()); + + static video::SColor color = video::SColor(255, 255, 255, 255); + int hit_capture_limit = + race_manager->getHitCaptureLimit() != std::numeric_limits::max() + ? race_manager->getHitCaptureLimit() : -1; + int score_limit = sw && !race_manager->hasTimeTarget() ? + race_manager->getMaxGoal() : ctf ? hit_capture_limit : -1; + if (!ctf && ffa && hit_capture_limit != -1) { + int icon_width = irr_driver->getActualScreenSize().Height/19; + core::rect indicator_pos(viewport.LowerRightCorner.X - (icon_width+10), + pos.UpperLeftCorner.Y, + viewport.LowerRightCorner.X - 10, + pos.UpperLeftCorner.Y + icon_width); + core::rect source_rect(core::position2d(0,0), + m_champion->getSize()); + draw2DImage(m_champion, indicator_pos, source_rect, + NULL, NULL, true); + + gui::ScalableFont* font = GUIEngine::getHighresDigitFont(); + font->setBlackBorder(true); + pos.UpperLeftCorner.X += 30; + font->draw(StringUtils::toWString(hit_capture_limit).c_str(), pos, color); + font->setBlackBorder(false); + font->setScale(1.0f); + return; + } + + if (ctf || sw) + { + if (score_limit != -1) + pos.UpperLeftCorner.X -= 80; + + int red_score = ctf ? ctf->getRedScore() : sw->getScore(KART_TEAM_RED); + int blue_score = ctf ? ctf->getBlueScore() : sw->getScore(KART_TEAM_BLUE); + gui::ScalableFont* font = GUIEngine::getHighresDigitFont(); font->setBlackBorder(true); font->setScale(scaling.Y < 1.0f ? 0.5f: 1.0f); - core::stringw text = StringUtils::toWString(ctf->getRedScore()); + core::stringw text = StringUtils::toWString(red_score); font->draw(text, pos, video::SColor(255, 255, 0, 0)); core::dimension2du d = font->getDimension(text.c_str()); pos += core::position2di(d.Width, 0); @@ -1238,9 +1201,17 @@ void RaceGUI::drawLap(const AbstractKart* kart, font->draw(text, pos, video::SColor(255, 255, 255, 255)); d = font->getDimension(text.c_str()); pos += core::position2di(d.Width, 0); - text = StringUtils::toWString(ctf->getBlueScore()); + text = StringUtils::toWString(blue_score); font->draw(text, pos, video::SColor(255, 0, 0, 255)); font->setScale(1.0f); + pos += core::position2di(d.Width, 0); + if (score_limit != -1) + { + text = L" ("; + text += StringUtils::toWString(score_limit); + text += L")"; + font->draw(text, pos, video::SColor(255, 255, 255, 255)); + } font->setBlackBorder(false); return; } @@ -1267,7 +1238,6 @@ void RaceGUI::drawLap(const AbstractKart* kart, pos.UpperLeftCorner.X -= icon_width; pos.LowerRightCorner.X -= icon_width; - static video::SColor color = video::SColor(255, 255, 255, 255); std::ostringstream out; out << lap + 1 << "/" << race_manager->getNumLaps(); diff --git a/src/states_screens/race_gui.hpp b/src/states_screens/race_gui.hpp index b183e1eec..1afa6f79e 100644 --- a/src/states_screens/race_gui.hpp +++ b/src/states_screens/race_gui.hpp @@ -99,6 +99,8 @@ private: irr::video::ITexture *m_blue_flag; irr::video::ITexture *m_soccer_ball; irr::video::ITexture *m_heart_icon; + /** Texture for the hit limit icon*/ + irr::video::ITexture* m_champion; /** Animation state: none, getting smaller (old value), * getting bigger (new number). */ @@ -140,8 +142,6 @@ private: void drawGlobalMiniMap (); void drawGlobalTimer (); void drawLiveDifference (); - void drawScores(); - public: From 092cd7f3bfaa52cb9255c07eab00f1e7dd1e42cd Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 16 Nov 2018 23:12:05 +0800 Subject: [PATCH 12/19] Fix #3583 --- data/gui/icons/mode_tt.png | Bin 6272 -> 4962 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/gui/icons/mode_tt.png b/data/gui/icons/mode_tt.png index c54a2bf1c7457bef1e347cd29f852a3c2f813464..9a89cf56ae426f6e48701aadfbe57a243f7beb7d 100644 GIT binary patch literal 4962 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 Date: Fri, 16 Nov 2018 23:34:05 +0800 Subject: [PATCH 13/19] Show kart name next to icon after finishing a race --- src/modes/linear_world.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index 629f1d709..3570801e8 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -627,6 +627,10 @@ void LinearWorld::getKartsDisplayInfo( } rank_info.m_text = irr::core::stringw(str.c_str()); } + else if (kart->hasFinishedRace()) + { + rank_info.m_text = kart->getController()->getName(); + } else { rank_info.m_text = ""; From e77eb2ccf6df3dfdc6e1406dfe6d986eab287640 Mon Sep 17 00:00:00 2001 From: Benau Date: Sat, 17 Nov 2018 00:48:48 +0800 Subject: [PATCH 14/19] Allow server owner to force soccer time / goal limits --- src/network/protocols/client_lobby.cpp | 4 +- src/network/protocols/client_lobby.hpp | 4 +- src/network/protocols/server_lobby.cpp | 20 +++++++-- src/network/server_config.hpp | 17 +++++--- src/states_screens/online/tracks_screen.cpp | 45 ++++++++++++--------- 5 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index 66ec4ec4f..973e7dc12 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -75,7 +75,7 @@ ClientLobby::ClientLobby(const TransportAddress& a, std::shared_ptr s) : LobbyProtocol(NULL) { m_waiting_for_game = false; - m_server_auto_lap = false; + m_server_auto_game_time = false; m_received_server_result = false; m_state.store(NONE); m_server_address = a; @@ -844,7 +844,7 @@ void ClientLobby::startSelection(Event* event) SFXManager::get()->quickSound("wee"); const NetworkString& data = event->data(); bool skip_kart_screen = data.getUInt8() == 1; - m_server_auto_lap = data.getUInt8() == 1; + m_server_auto_game_time = data.getUInt8() == 1; const unsigned kart_num = data.getUInt16(); const unsigned track_num = data.getUInt16(); m_available_karts.clear(); diff --git a/src/network/protocols/client_lobby.hpp b/src/network/protocols/client_lobby.hpp index 3d5a034a6..2c20de476 100644 --- a/src/network/protocols/client_lobby.hpp +++ b/src/network/protocols/client_lobby.hpp @@ -71,7 +71,7 @@ private: bool m_waiting_for_game; - bool m_server_auto_lap; + bool m_server_auto_game_time; bool m_received_server_result; @@ -111,7 +111,7 @@ public: { return m_state.load() == REQUESTING_CONNECTION; } bool isLobbyReady() const { return m_state.load() == CONNECTED; } bool isWaitingForGame() const { return m_waiting_for_game; } - bool isServerAutoLap() const { return m_server_auto_lap; } + bool isServerAutoGameTime() const { return m_server_auto_game_time; } virtual bool isRacing() const OVERRIDE { return m_state.load() == RACING; } void clearPlayers(); }; diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index da2be275c..977a2de95 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -883,7 +883,7 @@ void ServerLobby::startSelection(const Event *event) ns->setSynchronous(true); ns->addUInt8(LE_START_SELECTION).addUInt8( m_game_setup->isGrandPrixStarted() ? 1 : 0) - .addUInt8(ServerConfig::m_auto_lap_ratio > 0.0f ? 1 : 0); + .addUInt8(ServerConfig::m_auto_game_time_ratio > 0.0f ? 1 : 0); // Remove karts / tracks from server that are not supported on all clients std::set karts_erase, tracks_erase; @@ -1885,14 +1885,14 @@ void ServerLobby::playerVote(Event* event) if (race_manager->modeHasLaps()) { - if (ServerConfig::m_auto_lap_ratio > 0.0f) + if (ServerConfig::m_auto_game_time_ratio > 0.0f) { Track* t = track_manager->getTrack(track_name); if (t) { lap = (uint8_t)(fmaxf(1.0f, (float)t->getDefaultNumberOfLaps() * - ServerConfig::m_auto_lap_ratio)); + ServerConfig::m_auto_game_time_ratio)); } else { @@ -1904,6 +1904,20 @@ void ServerLobby::playerVote(Event* event) else if (lap == 0) lap = (uint8_t)3; } + else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER && + ServerConfig::m_auto_game_time_ratio > 0.0f) + { + if (m_game_setup->isSoccerGoalTarget()) + { + lap = (uint8_t)(ServerConfig::m_auto_game_time_ratio * + UserConfigParams::m_num_goals); + } + else + { + lap = (uint8_t)(ServerConfig::m_auto_game_time_ratio * + UserConfigParams::m_soccer_time_limit); + } + } NetworkString other = NetworkString(PROTOCOL_LOBBY_ROOM); std::string name = StringUtils::wideToUtf8(event->getPeer() diff --git a/src/network/server_config.hpp b/src/network/server_config.hpp index 15eff8fc7..739ddd1e9 100644 --- a/src/network/server_config.hpp +++ b/src/network/server_config.hpp @@ -238,12 +238,17 @@ namespace ServerConfig "(time-limit-threshold-ctf + flag-return-timemout / 60.0)) * 60.0," " negative value to disable time limit.")); - SERVER_CFG_PREFIX FloatServerConfigParam m_auto_lap_ratio - SERVER_CFG_DEFAULT(FloatServerConfigParam(-1.0f, "auto-lap-ratio", - "Value used by server to automatically calculate " - "lap of each race in network game, if more than 0.0f, the number of " - "lap of each track vote in linear race will be determined by " - "max(1.0f, auto-lap-ratio * default lap of that track).")); + SERVER_CFG_PREFIX FloatServerConfigParam m_auto_game_time_ratio + SERVER_CFG_DEFAULT(FloatServerConfigParam(-1.0f, "auto-game-time-ratio", + "Value used by server to automatically estimate each game time. " + "For races, it decides the lap of each race in network game, " + "if more than 0.0f, the number of lap of each track vote in " + "linear race will be determined by " + "max(1.0f, auto-game-time-ratio * default lap of that track). " + "For soccer if more than 0.0f, for time limit game it will be " + "auto-game-time-ratio * soccer-time-limit in UserConfig, for goal " + "limit game it will be auto-game-time-ratio * numgoals " + "in UserConfig, -1 to disable for all.")); SERVER_CFG_PREFIX IntServerConfigParam m_max_ping SERVER_CFG_DEFAULT(IntServerConfigParam(300, "max-ping", diff --git a/src/states_screens/online/tracks_screen.cpp b/src/states_screens/online/tracks_screen.cpp index ab2f5d3e4..9e546c92e 100644 --- a/src/states_screens/online/tracks_screen.cpp +++ b/src/states_screens/online/tracks_screen.cpp @@ -273,6 +273,8 @@ void TracksScreen::init() { // Notice: for arena (battle / soccer) lap and reverse will be mapped to // goals / time limit and random item location + auto cl = LobbyProtocol::get(); + assert(cl); if (UserConfigParams::m_num_laps == 0 || UserConfigParams::m_num_laps > 20) UserConfigParams::m_num_laps = 1; @@ -297,25 +299,34 @@ void TracksScreen::init() } else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER) { - m_laps->setVisible(true); - getWidget("lap-text")->setVisible(true); - auto cl = LobbyProtocol::get(); - assert(cl); - if (cl->getGameSetup()->isSoccerGoalTarget()) + if (cl->isServerAutoGameTime()) { - //I18N: In track screen - getWidget("lap-text")->setText(_("Number of goals to win"), false); - m_laps->setValue(UserConfigParams::m_num_goals); - m_laps->setMin(1); - m_laps->setMax(10); + getWidget("lap-text")->setVisible(false); + m_laps->setVisible(false); + m_laps->setValue(0); } else { - //I18N: In track screen - getWidget("lap-text")->setText(_("Maximum time (min.)"), false); - m_laps->setValue(UserConfigParams::m_soccer_time_limit); - m_laps->setMin(1); - m_laps->setMax(15); + m_laps->setVisible(true); + getWidget("lap-text")->setVisible(true); + auto cl = LobbyProtocol::get(); + assert(cl); + if (cl->getGameSetup()->isSoccerGoalTarget()) + { + //I18N: In track screen + getWidget("lap-text")->setText(_("Number of goals to win"), false); + m_laps->setValue(UserConfigParams::m_num_goals); + m_laps->setMin(1); + m_laps->setMax(10); + } + else + { + //I18N: In track screen + getWidget("lap-text")->setText(_("Maximum time (min.)"), false); + m_laps->setValue(UserConfigParams::m_soccer_time_limit); + m_laps->setMin(1); + m_laps->setMax(15); + } } getWidget("reverse-text")->setVisible(true); //I18N: In track screen @@ -325,9 +336,7 @@ void TracksScreen::init() } else { - auto cl = LobbyProtocol::get(); - assert(cl); - if (cl->isServerAutoLap()) + if (cl->isServerAutoGameTime()) { getWidget("lap-text")->setVisible(false); m_laps->setVisible(false); From 99eefa3797c51d455d64350bee491200264f040d Mon Sep 17 00:00:00 2001 From: Benau Date: Sat, 17 Nov 2018 01:07:06 +0800 Subject: [PATCH 15/19] Add missing isNetworking --- src/items/item_manager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/items/item_manager.cpp b/src/items/item_manager.cpp index ff49f9fe4..d6fd04896 100644 --- a/src/items/item_manager.cpp +++ b/src/items/item_manager.cpp @@ -265,7 +265,8 @@ Item* ItemManager::dropNewItem(ItemState::ItemType type, const Vec3 *server_xyz, const Vec3 *server_normal) { - if(NetworkConfig::get()->isClient() && !server_xyz) return NULL; + if (NetworkConfig::get()->isNetworking() && + NetworkConfig::get()->isClient() && !server_xyz) return NULL; Vec3 normal, pos; const Material* material_hit; if (!server_xyz) From 22999c1e2bb1af951e8d581b7e308fcf3adebef3 Mon Sep 17 00:00:00 2001 From: Benau Date: Sat, 17 Nov 2018 01:40:51 +0800 Subject: [PATCH 16/19] Fix #3581 --- data/items.xml | 2 +- src/items/item.cpp | 14 ++++++++++++-- src/items/item.hpp | 2 ++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/data/items.xml b/data/items.xml index dcd23f418..cdad77a91 100644 --- a/data/items.xml +++ b/data/items.xml @@ -8,7 +8,7 @@ isn't an item, it is internally handled as one, so list it here --> - + diff --git a/src/items/item.cpp b/src/items/item.cpp index 770b141ba..d97cd0fef 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -136,6 +136,16 @@ void ItemState::collected(const AbstractKart *kart) } } // collected +// ---------------------------------------------------------------------------- +/** Returns the graphical type of this item should be using (takes nolok into + * account). */ +Item::ItemType ItemState::getGrahpicalType() const +{ + return m_previous_owner && m_previous_owner->getIdent() == "nolok" && + getType() == ITEM_BUBBLEGUM ? + ITEM_BUBBLEGUM_NOLOK : getType(); +} // getGrahpicalType + // ============================================================================ /** Constructor for an item. * \param type Type of the item. @@ -184,7 +194,7 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal, } m_node = lodnode; setType(type); - handleNewMesh(getType()); + handleNewMesh(getGrahpicalType()); #ifdef DEBUG std::string debug_name("item: "); @@ -350,7 +360,7 @@ void Item::updateGraphics(float dt) if (m_graphical_type != getType()) { - handleNewMesh(getType()); + handleNewMesh(getGrahpicalType()); m_graphical_type = getType(); } diff --git a/src/items/item.hpp b/src/items/item.hpp index 5be813fea..94c6b7863 100644 --- a/src/items/item.hpp +++ b/src/items/item.hpp @@ -280,6 +280,8 @@ public: /** Returns the type of this item. */ ItemType getType() const { return m_type; } // ------------------------------------------------------------------------ + ItemType getGrahpicalType() const; + // ------------------------------------------------------------------------ /** Returns the original type of this item. */ ItemType getOriginalType() const { return m_original_type; } // ------------------------------------------------------------------------ From bb1aac3857150dfb87e85da04c6f504779967bfc Mon Sep 17 00:00:00 2001 From: Alayan-stk-2 Date: Fri, 16 Nov 2018 20:56:43 +0100 Subject: [PATCH 17/19] Fix the kart accelerating instead of slowing down when going backwards --- src/karts/kart.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index b9d24c5b0..cad3fb73d 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -2672,7 +2672,7 @@ float Kart::applyAirFriction(float engine_power) //Instead of making increasing gears have enormous power gaps, apply friction float mass_factor = m_kart_properties->getMass()/350.0f; - float compense_linear_slowdown = 39.33f*getSpeed()*mass_factor; + float compense_linear_slowdown = 39.33f*fabsf(getSpeed())*mass_factor; engine_power += compense_linear_slowdown; From e6dadeb980cebc44c94024892242ebe7a3f9c3e1 Mon Sep 17 00:00:00 2001 From: Benau Date: Sat, 17 Nov 2018 12:43:03 +0800 Subject: [PATCH 18/19] Use a larger radius for CTF --- src/modes/capture_the_flag.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modes/capture_the_flag.cpp b/src/modes/capture_the_flag.cpp index 7a3b653b0..1c5169733 100644 --- a/src/modes/capture_the_flag.cpp +++ b/src/modes/capture_the_flag.cpp @@ -35,7 +35,7 @@ #include const Vec3 g_kart_flag_offset(0.0, 0.2f, -0.5f); -const float g_capture_length = 2.0f; +const float g_capture_length = 3.0f; const int g_captured_score = 10; // ---------------------------------------------------------------------------- From 9c3bae5a87ecbdbbeeb87cf2b82f6ca52800cadf Mon Sep 17 00:00:00 2001 From: Benau Date: Sat, 17 Nov 2018 13:50:50 +0800 Subject: [PATCH 19/19] Use actualy screen size instead of frame size for font scaling --- src/font/font_with_face.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/font/font_with_face.cpp b/src/font/font_with_face.cpp index 8ef8c52f8..2af164d36 100644 --- a/src/font/font_with_face.cpp +++ b/src/font/font_with_face.cpp @@ -350,9 +350,9 @@ void FontWithFace::dumpGlyphPage() */ void FontWithFace::setDPI() { - const int screen_width = irr_driver->getFrameSize().Width; - const int screen_height = irr_driver->getFrameSize().Height; - + const int screen_width = irr_driver->getActualScreenSize().Width; + const int screen_height = irr_driver->getActualScreenSize().Height; + if (UserConfigParams::m_hidpi_enabled) { float scale = screen_height / 480.0f;