Compare commits

..

34 Commits

Author SHA1 Message Date
Gesche 7fc3229610 Merge branch 'master' of https://github.com/edubart/otclient 2019-02-02 11:44:17 +01:00
Konrad Kuśnierz d2a68ea301
Merge pull request #1008 from Arkamek/vs-settings
Fix glew32/zlib debug build.
2019-01-30 22:13:05 +01:00
Arkamek b231725294 Fix glew32/zlib debug mode 2019-01-30 16:19:56 +01:00
Konrad Kuśnierz 62a48a94ff
Merge pull request #919 from EgzoT/EgzoT-VS_OTC_upd_ver
Update OTClient outdated version in VS project
2019-01-16 14:16:20 +01:00
Konrad Kuśnierz 68872dd02c
Merge pull request #950 from codetriage-readme-bot/codetriage-badge
Add CodeTriage badge to edubart/otclient
2019-01-16 14:14:11 +01:00
Konrad Kuśnierz c1369a7c92
Merge branch 'master' into codetriage-badge 2019-01-16 14:13:18 +01:00
Konrad Kuśnierz c4dce79b15
Update README.md 2019-01-16 14:08:50 +01:00
Konrad Kuśnierz c58bf46f5e
Merge pull request #954 from DavidUser/feature/docker-support
Docker support
2019-01-16 14:08:09 +01:00
Konrad Kuśnierz 8b2bb127b0
Merge pull request #951 from EgzoT/EgzoT-setupViewMode_2_fix
Fix problem with display text in setupViewMode_2
2019-01-16 14:03:17 +01:00
Konrad Kuśnierz 33b60e842f
Merge pull request #966 from diath/msvc_fixes
Silence Windows SDK warnings when building with MSVC
2019-01-16 13:57:30 +01:00
Konrad Kuśnierz 70a95b2f04
Merge pull request #972 from EgzoT/EgzoT-UIComboBox_fix_getOption_to_isOption
Fixed getOption and rename to isOption
2019-01-16 13:56:20 +01:00
Konrad Kuśnierz e3b02a7c5d
Merge pull request #986 from okk3/patch-1
Function updateJump() fix
2019-01-16 13:53:14 +01:00
Konrad Kuśnierz 74d328206b
Merge pull request #1002 from diath/fix_magic_effects
Fix magic effect animations in newer client versions
2019-01-16 13:50:51 +01:00
Konrad Kuśnierz db3ba0f679
Merge pull request #1006 from diath/improve_scrollbar_navigation
Improve scrollbar navigation
2019-01-16 13:36:33 +01:00
Konrad Kuśnierz d563aafbc9
Merge pull request #990 from EgzoT/EgzoT-Show_more_information_in_stamina_bar_2
Show more information in stamina bar
2019-01-16 13:35:05 +01:00
Konrad Kuśnierz 7e31980ba3
Merge pull request #965 from diath/fix_tab_blink
Fix tab blink
2019-01-16 13:32:39 +01:00
Konrad Kuśnierz f7ceb788e8
Merge pull request #1004 from diath/add_channel_events
Add support for channel events
2019-01-16 13:30:09 +01:00
Konrad Kuśnierz 710212c23a
Merge pull request #1003 from diath/fix_keyboard_desc
Fix an issue with key combo desc not working properly with integer keys
2019-01-16 13:25:37 +01:00
Kamil Chojnowski a40130d79b Fix magic effect animations in newer client versions 2019-01-06 06:17:25 +01:00
Kamil Chojnowski 8301bc74f3 Add support for channel events 2019-01-05 22:22:01 +01:00
Kamil Chojnowski c4be084516 Fix an issue with key combo desc not working properly with integer keys 2019-01-05 19:31:19 +01:00
Kamil Chojnowski 57a1f5eebe Improve scrollbar navigation 2019-01-05 18:13:36 +01:00
EgzoT 0e8464bd42
Show more information in stamina bar
1. Change colors on certain values, when stamina time was change.
2. Change tooltip on certain values, when stamina time was change.
3. Work with most protocols, including the most popular (8.54 - 10.98).
4. In protocols >= 1031 use information about premium account to show if player have premium stamina time.
2018-09-03 16:33:07 +02:00
Okke a93333ddbf
Function updateJump() fix
nextT should cast double as it's a second degree equation and results in a double type. -> Bhaskara.
2018-08-06 00:08:37 +02:00
EgzoT 95ce65d8cc
Fixed getOption and rename to isOption
Fixed getOption who always return nil.
Rename getOption to isOption.
2018-06-09 18:08:56 +02:00
Kamil Chojnowski 1bd392aba9 Silence Windows SDK warnings when building with MSVC 2018-04-23 14:33:08 +02:00
Kamil Chojnowski ba558404d3 Fix tab blink 2018-04-23 14:29:39 +02:00
David Kennedy S. A d03ffc1f26 Enable any client connect to X host 2018-03-28 11:57:59 -03:00
David Kennedy S. A 251c937b7e Disable SE Linux when running the client on container 2018-03-21 01:56:38 -03:00
David Kennedy S. A 934513df80 Build and run with docker container 2018-03-21 01:55:51 -03:00
David Kennedy S. A 9142a096df Add dockerfile to build ubuntu version 2018-03-21 01:54:10 -03:00
EgzoT 9daec49212
Fix problem with display text in setupViewMode_2
Fix problem with display text messages in setupViewMode - 2 ([CTRL + .] x 2).
Status messages was display in other place (higher than player character).
2018-03-05 11:43:38 +01:00
codetriage-readme-bot 2b1feb1586 Add CodeTriage badge to edubart/otclient
Adds a badge showing the number of people helping this repo on CodeTriage.

[![Open Source Helpers](https://www.codetriage.com/edubart/otclient/badges/users.svg)](https://www.codetriage.com/edubart/otclient)

## What is CodeTriage?

CodeTriage is an Open Source app that is designed to make contributing to Open Source projects easier. It works by sending subscribers a few open issues in their inbox. If subscribers get busy, there is an algorithm that backs off issue load so they do not get overwhelmed

[Read more about the CodeTriage project](https://www.codetriage.com/what).

## Why am I getting this PR?

Your project was picked by the human, @schneems. They selected it from the projects submitted to https://www.codetriage.com and hand edited the PR. How did your project get added to [CodeTriage](https://www.codetriage.com/what)? Roughly about 1 year ago, [Tarjei400](https://github.com/Tarjei400) added this project to CodeTriage in order to start contributing. Since then, 5 people have subscribed to help this repo.

## What does adding a badge accomplish?

Adding a badge invites people to help contribute to your project. It also lets developers know that others are invested in the longterm success and maintainability of the project.

You can see an example of a CodeTriage badge on these popular OSS READMEs:

- [![Email clients like GMAIL do not render SVG images](https://www.codetriage.com/rails/rails/badges/users.svg)](https://www.codetriage.com/rails/rails) https://github.com/rails/rails
- [![Email clients like GMAIL do not render SVG images](https://www.codetriage.com/crystal-lang/crystal/badges/users.svg)](https://www.codetriage.com/crystal-lang/crystal) https://github.com/crystal-lang/crystal

## Have a question or comment?

While I am a bot, this PR was manually reviewed and monitored by a human - @schneems. My job is writing commit messages and handling PR logistics.

If you have any questions, you can reply back to this PR and they will be answered by @schneems. If you do not want a badge right now, no worries, close the PR, you will not hear from me again.

Thanks for making your project Open Source! Any feedback is greatly appreciated.
2018-02-27 14:13:10 -06:00
EgzoT 1eda9b441f
Update OTClient outdated version in VS project
Change OTClient version from 0.6.3 to 0.6.6 in Visual Studio project.
2017-11-28 22:17:06 +01:00
21 changed files with 257 additions and 30 deletions

31
Dockerfile Normal file
View File

@ -0,0 +1,31 @@
from ubuntu:latest
WORKDIR /app
RUN apt-get update; apt-get install -y \
build-essential \
cmake \
git-core \
libboost-all-dev \
libglew-dev \
liblua5.1-0-dev \
libopenal-dev \
libphysfs-dev \
libssl-dev \
libvorbis-dev \
zlib1g-dev
RUN apt-get install -y \
libncurses5-dev \
mercurial; \
hg clone -r stable-2.0 http://hg.icculus.org/icculus/physfs/; \
cd physfs; \
mkdir build && cd build && cmake .. && make && make install; \
mv /usr/local/lib/libphysfs.a /usr/lib/x86_64-linux-gnu/.
ADD . /app
# Build application
RUN mkdir -p build && cd build && cmake .. && make -j$(grep -c ^process /proc/cpuinfo);
CMD cd build; ./otclient

View File

@ -37,6 +37,15 @@ In short, if you need to compile OTClient, follow these tutorials:
* [Compiling on Linux](https://github.com/edubart/otclient/wiki/Compiling-on-Linux)
* [Compiling on OS X](https://github.com/edubart/otclient/wiki/Compiling-on-Mac-OS-X)
### Build and run with Docker
To build and run the client:
```
./build.sh
./run.sh
```
The build step should be run just when something on implementation changes.
### Need help?

3
build.sh Executable file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
docker build -t edubart/otclient .

View File

@ -26,6 +26,11 @@ local function retranslateKeyComboDesc(keyComboDesc)
if keyComboDesc == nil then
error('Unable to translate key combo \'' .. keyComboDesc .. '\'')
end
if type(keyComboDesc) == 'number' then
keyComboDesc = tostring(keyComboDesc)
end
local keyCombo = {}
for i,currentKeyDesc in ipairs(keyComboDesc:split('+')) do
for keyCode, keyDesc in pairs(KeyCodeDescs) do

View File

@ -19,13 +19,14 @@ function UIComboBox:clearOptions()
self:clearText()
end
function UIComboBox:getOption(text)
if not self.options then return nil end
function UIComboBox:isOption(text)
if not self.options then return false end
for i,v in ipairs(self.options) do
if v.text == text then
return nil
return true
end
end
return false
end
function UIComboBox:setOption(text, dontSignal)

View File

@ -385,6 +385,11 @@ function UIMoveableTabBar:selectTab(tab)
tab:setOn(false)
tab.blinking = false
if tab.blinkEvent then
removeEvent(tab.blinkEvent)
tab.blinkEvent = nil
end
local parent = tab:getParent()
parent:focusChild(tab, MouseFocusReason)
updateNavigation(self)

View File

@ -126,8 +126,8 @@ end
function UIScrollBar:onSetup()
self.setupDone = true
local sliderButton = self:getChildById('sliderButton')
g_mouse.bindAutoPress(self:getChildById('decrementButton'), function() self:decrement() end, 300)
g_mouse.bindAutoPress(self:getChildById('incrementButton'), function() self:increment() end, 300)
g_mouse.bindAutoPress(self:getChildById('decrementButton'), function() self:onDecrement() end, 300)
g_mouse.bindAutoPress(self:getChildById('incrementButton'), function() self:onIncrement() end, 300)
g_mouse.bindPressMove(sliderButton, function(mousePos, mouseMoved) parseSliderPos(self, sliderButton, mousePos, mouseMoved) end)
g_mouse.bindPress(sliderButton, function(mousePos, mouseButton) parseSliderPress(self, sliderButton, mousePos, mouseButton) end)
@ -158,6 +158,26 @@ function UIScrollBar:onStyleApply(styleName, styleNode)
end
end
function UIScrollBar:onDecrement()
if g_keyboard.isCtrlPressed() then
self:decrement(self.value)
elseif g_keyboard.isShiftPressed() then
self:decrement(10)
else
self:decrement()
end
end
function UIScrollBar:onIncrement()
if g_keyboard.isCtrlPressed() then
self:increment(self.maximum)
elseif g_keyboard.isShiftPressed() then
self:increment(10)
else
self:increment()
end
end
function UIScrollBar:decrement(count)
count = count or self.step
self:setValue(self.value - count)

View File

@ -52,6 +52,13 @@ SayModes = {
[3] = { speakTypeDesc = 'yell', icon = '/images/game/console/yell' }
}
ChannelEventFormats = {
[ChannelEvent.Join] = '%s joined the channel.',
[ChannelEvent.Leave] = '%s left the channel.',
[ChannelEvent.Invite] = '%s has been invited to the channel.',
[ChannelEvent.Exclude] = '%s has been removed from the channel.',
}
MAX_HISTORY = 500
MAX_LINES = 100
HELP_CHANNEL = 9
@ -98,7 +105,8 @@ function init()
onRuleViolationCancel = onRuleViolationCancel,
onRuleViolationLock = onRuleViolationLock,
onGameStart = online,
onGameEnd = offline
onGameEnd = offline,
onChannelEvent = onChannelEvent,
})
consolePanel = g_ui.loadUI('console', modules.game_interface.getBottomPanel())
@ -240,7 +248,8 @@ function terminate()
onRuleViolationCancel = onRuleViolationCancel,
onRuleViolationLock = onRuleViolationLock,
onGameStart = online,
onGameEnd = offline
onGameEnd = offline,
onChannelEvent = onChannelEvent,
})
if g_game.isOnline() then clear() end
@ -1437,3 +1446,19 @@ function offline()
end
clear()
end
function onChannelEvent(channelId, name, type)
local fmt = ChannelEventFormats[type]
if not fmt then
print(('Unknown channel event type (%d).'):format(type))
return
end
local channel = channels[channelId]
if channel then
local tab = getTab(channel)
if tab then
addTabText(fmt:format(name), SpeakTypesSettings.channelOrange, tab)
end
end
end

View File

@ -120,7 +120,7 @@ function setSkillTooltip(id, value)
widget:setTooltip(value)
end
function setSkillPercent(id, percent, tooltip)
function setSkillPercent(id, percent, tooltip, color)
local skill = skillsWindow:recursiveGetChildById(id)
local widget = skill:getChildById('percent')
if widget then
@ -129,6 +129,10 @@ function setSkillPercent(id, percent, tooltip)
if tooltip then
widget:setTooltip(tooltip)
end
if color then
widget:setBackgroundColor(color)
end
end
end
@ -333,10 +337,34 @@ function onStaminaChange(localPlayer, stamina)
if minutes < 10 then
minutes = '0' .. minutes
end
local percent = math.floor(100 * stamina / (42 * 60)) -- max is 42 hours
local percent = math.floor(100 * stamina / (42 * 60)) -- max is 42 hours --TODO not in all client versions
setSkillValue('stamina', hours .. ":" .. minutes)
setSkillPercent('stamina', percent, tr('You have %s percent', percent))
--TODO not all client versions have premium time
if stamina > 2400 and g_game.getClientVersion() >= 1038 and localPlayer:isPremium() then
local text = tr("You have %s hours and %s minutes left", hours, minutes) .. '\n' ..
tr("Now you will gain 50%% more experience")
setSkillPercent('stamina', percent, text, 'green')
elseif stamina > 2400 and g_game.getClientVersion() >= 1038 and not localPlayer:isPremium() then
local text = tr("You have %s hours and %s minutes left", hours, minutes) .. '\n' ..
tr("You will not gain 50%% more experience because you aren't premium player, now you receive only 1x experience points")
setSkillPercent('stamina', percent, text, '#89F013')
elseif stamina > 2400 and g_game.getClientVersion() < 1038 then
local text = tr("You have %s hours and %s minutes left", hours, minutes) .. '\n' ..
tr("If you are premium player, you will gain 50%% more experience")
setSkillPercent('stamina', percent, text, 'green')
elseif stamina <= 2400 and stamina > 840 then
setSkillPercent('stamina', percent, tr("You have %s hours and %s minutes left", hours, minutes), 'orange')
elseif stamina <= 840 and stamina > 0 then
local text = tr("You have %s hours and %s minutes left", hours, minutes) .. "\n" ..
tr("You gain only 50%% experience and you don't may gain loot from monsters")
setSkillPercent('stamina', percent, text, 'red')
elseif stamina == 0 then
local text = tr("You have %s hours and %s minutes left", hours, minutes) .. "\n" ..
tr("You don't may receive experience and loot from monsters")
setSkillPercent('stamina', percent, text, 'black')
end
end
function onOfflineTrainingChange(localPlayer, offlineTrainingTime)

View File

@ -8,7 +8,7 @@ TextMessageLabel < UILabel
Panel
anchors.fill: gameMapPanel
anchors.bottom: gameBottomPanel.top
anchors.bottom: gameMapPanel.bottom
focusable: false
Panel

View File

@ -333,4 +333,11 @@ SubscriptionStatus = {
Premium = 1,
}
ChannelEvent = {
Join = 0,
Leave = 1,
Invite = 2,
Exclude = 3,
}
-- @}

19
run.sh Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env bash
SE_enforcing=`getenforce` || true
sudo setenforce Permissive || true
# Enable any host to connect on X Org
xhost +
docker run -ti --rm \
-e DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
--device /dev/dri \
edubart/otclient
# Enable any host to connect on X Org
xhost -
sudo setenforce $SE_enforcing || true

View File

@ -123,6 +123,24 @@ int Animator::getPhase()
return m_phase;
}
int Animator::getPhaseAt(ticks_t time)
{
int index = 0;
ticks_t total = 0;
for(const auto &pair: m_phaseDurations) {
total += std::get<1>(pair);
if (time < total) {
return index;
}
++index;
}
return std::min<int>(index, m_animationPhases - 1);
}
int Animator::getStartPhase()
{
if(m_startPhase > -1)
@ -197,3 +215,13 @@ void Animator::calculateSynchronous()
}
m_lastPhaseTicks = ticks;
}
ticks_t Animator::getTotalDuration()
{
ticks_t time = 0;
for (const auto &pair: m_phaseDurations) {
time += std::get<1>(pair);
}
return time;
}

View File

@ -50,12 +50,15 @@ public:
void setPhase(int phase);
int getPhase();
int getPhaseAt(ticks_t time);
int getStartPhase();
int getAnimationPhases() { return m_animationPhases; }
bool isAsync() { return m_async; }
bool isComplete() { return m_isComplete; }
ticks_t getTotalDuration();
void resetAnimation();
private:

View File

@ -405,7 +405,7 @@ void Creature::updateJump()
int nextT, i = 1;
do {
nextT = stdext::round((-b + std::sqrt(std::max<int>(b*b + 4*a*(roundHeight+diff*i), 0.0)) * diff) / (2*a));
nextT = stdext::round((-b + std::sqrt(std::max<double>(b*b + 4*a*(roundHeight+diff*i), 0.0)) * diff) / (2*a));
++i;
if(nextT < halfJumpDuration)

View File

@ -22,6 +22,7 @@
#include "effect.h"
#include "map.h"
#include "game.h"
#include <framework/core/eventdispatcher.h>
void Effect::drawEffect(const Point& dest, float scaleFactor, bool animate, int offsetX, int offsetY, LightView *lightView)
@ -30,8 +31,20 @@ void Effect::drawEffect(const Point& dest, float scaleFactor, bool animate, int
return;
int animationPhase = 0;
if(animate)
animationPhase = std::min<int>((int)(m_animationTimer.ticksElapsed() / m_phaseDuration), getAnimationPhases() - 1);
if(animate) {
if(g_game.getFeature(Otc::GameEnhancedAnimations)) {
// This requires a separate getPhaseAt method as using getPhase would make all magic effects use the same phase regardless of their appearance time
animationPhase = rawGetThingType()->getAnimator()->getPhaseAt(m_animationTimer.ticksElapsed());
} else {
// hack to fix some animation phases duration, currently there is no better solution
int ticks = EFFECT_TICKS_PER_FRAME;
if (m_id == 33) {
ticks <<= 2;
}
animationPhase = std::min<int>((int)(m_animationTimer.ticksElapsed() / ticks), getAnimationPhases() - 1);
}
}
int xPattern = offsetX % getNumPatternX();
if(xPattern < 0)
@ -47,15 +60,24 @@ void Effect::drawEffect(const Point& dest, float scaleFactor, bool animate, int
void Effect::onAppear()
{
m_animationTimer.restart();
m_phaseDuration = EFFECT_TICKS_PER_FRAME;
int duration = 0;
if(g_game.getFeature(Otc::GameEnhancedAnimations)) {
duration = getThingType()->getAnimator()->getTotalDuration();
} else {
duration = EFFECT_TICKS_PER_FRAME;
// hack to fix some animation phases duration, currently there is no better solution
if(m_id == 33)
m_phaseDuration <<= 2;
if(m_id == 33) {
duration <<= 2;
}
duration *= getAnimationPhases();
}
// schedule removal
auto self = asEffect();
g_dispatcher.scheduleEvent([self]() { g_map.removeThing(self); }, m_phaseDuration * getAnimationPhases());
g_dispatcher.scheduleEvent([self]() { g_map.removeThing(self); }, duration);
}
void Effect::setId(uint32 id)

View File

@ -51,7 +51,6 @@ protected:
private:
Timer m_animationTimer;
uint m_phaseDuration;
uint16 m_id;
};

View File

@ -1903,9 +1903,11 @@ void ProtocolGame::parseQuestLine(const InputMessagePtr& msg)
void ProtocolGame::parseChannelEvent(const InputMessagePtr& msg)
{
msg->getU16(); // channel id
g_game.formatCreatureName(msg->getString()); // player name
msg->getU8(); // event type
uint16 channelId = msg->getU16();
std::string name = g_game.formatCreatureName(msg->getString());
uint8 type = msg->getU8();
g_lua.callGlobalField("g_game", "onChannelEvent", channelId, name, type);
}
void ProtocolGame::parseItemInfo(const InputMessagePtr& msg)

View File

@ -29,7 +29,19 @@
#include <winsock2.h>
#include <windows.h>
#include <process.h>
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable:4091) // warning C4091: 'typedef ': ignored on left of '' when no variable is declared
#include <imagehlp.h>
#pragma warning (pop)
#else
#include <imagehlp.h>
#endif
const char *getExceptionName(DWORD exceptionCode)
{

View File

@ -23,13 +23,21 @@
#include "demangle.h"
#ifdef _MSC_VER
#include <winsock2.h>
#include <windows.h>
#pragma warning (push)
#pragma warning (disable:4091) // warning C4091: 'typedef ': ignored on left of '' when no variable is declared
#include <dbghelp.h>
#pragma warning (pop)
#else
#include <cxxabi.h>
#include <cstring>
#include <cstdlib>
#endif
namespace stdext {

View File

@ -25,7 +25,7 @@
BUILD_TYPE="RelWithDebInfo";
BUILD_COMMIT="devel";
BUILD_REVISION="0";
VERSION="0.6.3";
VERSION="0.6.6";
AB
</PREPROCESSOR_DEFS>
@ -85,8 +85,8 @@
</OTCLIENT_LIBDEPS>
<OTCLIENT_LIBDEPS_D>
glew32.lib;
zlib.lib;
glew32d.lib;
zlibd.lib;
libeay32.lib;
physfs.lib;
openal32.lib;