User:Illviljan: Difference between revisions
Jump to navigation
Jump to search
>Illviljan No edit summary |
>Illviljan mNo edit summary |
||
(85 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
==Subpages== | |||
{{Subpages}} | |||
{{ | ==Todo list== | ||
* Align passive skill tables with {{tlx|Item table}} by adding the parameters to pages using them: | |||
** [[Template:Query ascendancy passive skills]] | |||
** [[Template:Query base passive skills]] | |||
** [[Template:Query keystone passive skills]] | |||
** [[Template:Query passive skills]] | |||
* Add option to remove column in item table if it's completely empty, relevant for {{tlx|Area item drops}}. | |||
==Scripts== | |||
{{cot|Matlab scripts}} | |||
{{cot|Experience Penalty. Last updated: 2016-09-02}}<pre> | |||
%% Experience Penalty | |||
% The player also suffers a penalty to XP if the player is too far above | |||
% or below the monster's level. | |||
home, clear all, close all | |||
%% Input | |||
PlayerLevel = 1:100; %[30, 10]; | |||
MonsterLevel = 1:90; | |||
%% Calculations | |||
% Create a repeated matrix: | |||
mPlayerLevel = repmat(PlayerLevel, length(MonsterLevel), 1); | |||
mMonsterLevel = repmat(MonsterLevel, length(PlayerLevel), 1)'; | |||
% Minimum amount of experience penalty: | |||
minEXPMulti = 0.01; | |||
% There's a safe zone between player level and monster level where no | |||
% experience penalty is applied: | |||
SafeZone = floor(3 + mPlayerLevel/16); | |||
% Any additional level difference in excess of this safe range is the | |||
% effective level difference: | |||
EffectiveDifference = max(abs(mPlayerLevel - mMonsterLevel) - SafeZone, 0); | |||
% If the effective difference is negative that implies the player is inside | |||
% the safe zone. Therefore only values =>0 are relevant. | |||
% If the player level is outside the safe zone a multiplier on monsters | |||
% experience takes effect, reducing the amount. There are two penalties, | |||
% one at lower levels and one at higher levels. | |||
% Low levels: | |||
XPMultiplier_Low = ((mPlayerLevel + 5) ./ (mPlayerLevel + 5 + EffectiveDifference.^2.5)).^1.5; | |||
% High Levels: | |||
LevelThreshold = 95; | |||
BoolHighPenalty = mPlayerLevel >= LevelThreshold; | |||
XPMultiplier_High = (1 - 1 ./ (1 + 0.1 * (mPlayerLevel - 94))) .* BoolHighPenalty; | |||
XPMultiplier_High(isnan(XPMultiplier_High)) = 0; | |||
% Total penalty: | |||
XPMultiplier_Tot = max(XPMultiplier_Low .* (1 - XPMultiplier_High), minEXPMulti); | |||
%% Contour plot | |||
figure('position', [500, 500, 1100, 600]) | |||
[C,h] = contourf(mPlayerLevel, mMonsterLevel, XPMultiplier_Tot); | |||
ticks = 5; | |||
set(gca,'XTick',0:ticks:PlayerLevel(end)); | |||
set(gca,'YTick',0:ticks:MonsterLevel(end)); | |||
h = colorbar; | |||
h.Limits = [0.01 1]; | |||
grid minor | |||
shading interp | |||
title('Experience Penalty') | |||
xlabel('Player Level') | |||
ylabel('Monster Level') | |||
% zlabel('Experience efficiency') | |||
ylabel(h,'Experience Efficiency'); | |||
%% Party play | |||
% Parties with different character levels will gain different amount of | |||
% experience according to: | |||
PercentualShare = (PlayerLevel + 10).^2.71 ./ sum((PlayerLevel + 10).^2.71,2); | |||
</pre>{{cob}} | |||
{{cot|Chance to hit and avoid attacks. Last updated: 2015-12-10}}<pre> | |||
%% Chance to hit and avoid attacks. | |||
close all, clear all, home | |||
set(0,'DefaultFigureWindowStyle', 'docked'); | |||
% Sources: | |||
% http://pathofexile.gamepedia.com/Evasion | |||
% http://pathofexile.gamepedia.com/Accuracy | |||
%% Input | |||
step = 100; | |||
evasionRating = linspace(0, 50000, step); | |||
attackerAccuracy = linspace(0, 4000, step); | |||
chanceToDodge = 0; | |||
%% Calculations | |||
% Create a Mesh grid to be able to do contour plots: | |||
[evasionRatingMesh, attackerAccuracyMesh] = meshgrid(evasionRating, attackerAccuracy); | |||
% Chance to hit is a function if accuracy and evasion rating: | |||
chanceToHit = min(max( attackerAccuracyMesh ./ (attackerAccuracyMesh + (evasionRatingMesh/4).^0.8), 0.05) , 0.95); | |||
% Chance to avoid hits | |||
chanceToAvoidHit = 1 - chanceToHit*(1-chanceToDodge); | |||
%% Contour plot | |||
% Chance to avoid hit contour plot | |||
figure | |||
[C,h] = contourf(evasionRatingMesh,attackerAccuracyMesh,chanceToAvoidHit*100); | |||
clabel(C,h,'labelspacing',200) | |||
% clabel(C,h,'manual') | |||
colormap(cool) | |||
h = colorbar; | |||
h.Limits = [5 95]; | |||
grid minor | |||
shading interp | |||
title('Chance to avoid enemy attacks') | |||
xlabel('Defender''s Evasion Rating') | |||
ylabel('Attacker''s Accuracy Rating') | |||
ylabel(h,'Chance to avoid hit [%]'); | |||
% Chance to hit contour plot | |||
figure | |||
[C,h] = contourf(attackerAccuracyMesh,evasionRatingMesh, chanceToHit*100); | |||
clabel(C,h,'labelspacing',700) | |||
colormap(cool) | |||
h = colorbar; | |||
h.Limits = [5 95]; | |||
grid minor | |||
shading interp | |||
title('Chance to hit enemy') | |||
xlabel('Attacker''s Accuracy Rating') | |||
ylabel('Defender''s Evasion Rating') | |||
% zlabel('Experience efficiency') | |||
ylabel(h,'Chance to hit [%]'); | |||
</pre>{{cob}} | |||
{{cot|Armour Reduction. Last updated: 2015-12-10}}<pre> | |||
%% Armour Reduction | |||
close all, clear all, home | |||
% Sources: | |||
% http://pathofexile.gamepedia.com/Armour | |||
%% Input | |||
step = 100; | |||
Armour = linspace(0, 50000, step); | |||
Damage = linspace(0, 10000, step); | |||
%% Calculations | |||
% Create a Mesh grid to be able to do contour plots: | |||
[ArmourMesh, DamageMesh] = meshgrid(Armour, Damage); | |||
Damage_Reduction_FactorMesh = ArmourMesh ./ (ArmourMesh + 10 * DamageMesh); | |||
%% Contour plot | |||
figure | |||
% [C,h] = contourf(ArmourMesh,DamageMesh,Damage_Reduction_FactorMesh*100); | |||
[C,h] = contour(ArmourMesh,Damage_Reduction_FactorMesh*100,DamageMesh, ... | |||
[100:200:600, 1000:500:2000, 3000:1000:6000, 8000:2000:10000]); | |||
clabel(C,h, 'labelspacing',700); | |||
clabel(C,h,'manual') | |||
colormap(copper) | |||
h = colorbar; | |||
% h.Limits = [0.01 1]; | |||
grid minor | |||
shading interp | |||
ylim([0 90]) | |||
title('Physical Damage Reduction when Hit') | |||
xlabel('Armour Rating') | |||
ylabel('#% additional Physical Damage Reduction when Hit') | |||
ylabel(h,'Raw Physical Damage'); | |||
</pre>{{cob}} | |||
{{cot|Plot Energy shield recharge. Last updated: 2015-12-10}}<pre> | |||
%% Plot Energy shield recharge | |||
close all, clear all, home | |||
% Sources: | |||
% http://pathofexile.gamepedia.com/Energy_shield | |||
%% Inputs | |||
r = 0:300; | |||
BaseStart = 2; | |||
%% Calculations | |||
ESStartTime = BaseStart * 100./(100 + r); | |||
%% Plot | |||
figure | |||
plot(r, ESStartTime) | |||
title('Start of Energy Shield Recharge') | |||
xlabel('#% faster start of Energy Shield Recharge') | |||
ylabel('Start time of Energy Shield Recharge [s]') | |||
grid on | |||
</pre>{{cob}} | |||
{{cot|Leech Mechanics. Last updated: 2017-01-01}}<pre> | |||
%% Leech mechanics for Path of Exile | |||
% This script analyses how the leech rate changes with increasing number of | |||
% enemies and number of hits on the enemy. | |||
close all, clear all, home | |||
set(0,'DefaultFigureWindowStyle', 'docked'); | |||
%% Input | |||
hp = 5000; % Maximum Life/Mana. | |||
l = 0.05; % Damage Leeched as Life/Mana. | |||
m = 2.50; % increased Life/Mana Leeched per second. | |||
m_max = 0.15; % of maximum Life/Mana per second to | |||
% maximum Life/Mana Leech rate. | |||
% Damage values from the hit: | |||
damage = 500000/12; % Damage dealt. | |||
attacksPerSec = 12; % Attacks per Second. | |||
mobsPerAttack = 1; % Enemies hit by one attack. | |||
numberOfAttacks = 7; % Number of attacks done to enemies. | |||
% The time when the attack started: | |||
attackTime = 0:1/attacksPerSec:(numberOfAttacks - 1)/attacksPerSec; | |||
% The time when the attack hit the target(s): | |||
hitTime = kron(attackTime, ones(1,mobsPerAttack)); | |||
q = 0.02; % Base Leech Rate. | |||
q_max = 0.20; % Base Maximum Leech Rate. | |||
steps = 1000; % Number of steps. | |||
%% Calculations | |||
% Maximum recovery rate: | |||
recovery_rate_max = (q_max + m_max) * hp; | |||
% Leech duration: | |||
duration_i = floor(damage * l) / (hp *q) .* ones(1, length(hitTime)); | |||
% Total allowed leech instance to not exceed the maximum recovery rate: | |||
n_tot = (q_max + m_max) / (q * (1 + m)); | |||
% Maximum analysis time: | |||
maxTime = hitTime(end) + duration_i(end); | |||
% Time between each step: | |||
dt = (maxTime-0)/steps; | |||
% Repeat vectors: | |||
t = 0:dt:maxTime; | |||
tRep = repmat(t, length(hitTime), 1); | |||
instanceRep = repmat((1:length(hitTime))', 1, length(t)); | |||
AttackTimeRep = repmat(hitTime', 1, length(t)); | |||
durationRep = repmat(duration_i', 1, length(t)); | |||
% Boolean conditions to check if there have been an enemy hit and if | |||
% the leeched ife is lower than the total amount of life leeched. | |||
boolHitStart = tRep >= AttackTimeRep; | |||
boolLeechEnd = tRep < AttackTimeRep + durationRep; | |||
BoolLeechEndVP = tRep <= AttackTimeRep + dt*0.99; | |||
% Both of the above conditions must be true for leech to occur: | |||
boolLeech = (boolHitStart .* boolLeechEnd); | |||
boolLeechVP = (boolHitStart .* BoolLeechEndVP); | |||
% Base Recovery Rate for each leech instance: | |||
recovery_rate_i = hp * q * (1 + m) .* boolLeech; | |||
% Each active leech instance: | |||
leechInstance = instanceRep .* boolLeech; | |||
% Base Recovery Rate summarized for all the leech instances: | |||
recovery_rate_sum = sum(recovery_rate_i,1); | |||
% Check that r_sum is not greater than r_max: | |||
boolLimit = recovery_rate_sum >= recovery_rate_max; | |||
recovery_rate_sum = recovery_rate_max .* boolLimit ... | |||
+ recovery_rate_sum .*(~boolLimit); | |||
% Pre-load for for-loop: | |||
hp_recovered_i = zeros(length(hitTime), length(t)); | |||
hp_recovered_tot = zeros(1, length(t)); | |||
hp_recovered_totVP = zeros(1, length(t)); | |||
for i = 1:length(t)-1; | |||
% HP restored from each leech instance, this is used to check | |||
% when each leech instance is finished: | |||
hp_recovered_i(:,i+1) = q * hp .* boolLeech(:,i) * dt ... | |||
+ hp_recovered_i(:,i); | |||
% Total HP restored from all the leech instances: | |||
hp_recovered_tot(:,i+1) = recovery_rate_sum(:,i) * dt ... | |||
+ hp_recovered_tot(:,i); | |||
% Vaal Pact restores life instanteously: | |||
hp_recovered_totVP(:,i+1) = damage * l .* sum(boolLeechVP(:,i),1) ... | |||
+ hp_recovered_totVP(:,i); | |||
end | |||
%% Plot | |||
figure | |||
leechInstance(leechInstance == 0) = NaN; % Remove zeros from plot. | |||
fig(1) = subplot(3,1,1); | |||
colororder = get(gca,'colororder'); | |||
plot(t, leechInstance, 'Color', colororder(1,:)); | |||
% set(gca, 'YTick', 0:length(hitTime)); % Show integers only. | |||
ylim([0 length(hitTime)+0.5]); | |||
xlim([0 maxTime]); | |||
xlabel('Time, t, [s]'); | |||
ylabel('Leech instance'); | |||
title('Leech instance'); | |||
for i = 1:length(hitTime); | |||
hold on | |||
% Find the start and end point of each instance and mark it: | |||
[rowStart, colStart] = find(~isnan(leechInstance(i,:)), 1, 'first'); | |||
[rowEnd, colEnd] = find(~isnan(leechInstance(i,:)), 1, 'last'); | |||
plot(t(colStart), leechInstance(i, colStart), 'b.', ... | |||
t(colEnd), leechInstance(i, colEnd),'bx', ... | |||
t(colStart), leechInstance(i, colStart),'ro'); | |||
% Vaal Pact Start and End: | |||
plot(t(colStart), leechInstance(i, colStart),'ro'); | |||
end | |||
fig(2) = subplot(3,1,2); | |||
[ax, h1, h2] = plotyy(t, recovery_rate_sum, t, recovery_rate_sum/hp); | |||
delete(h2); | |||
NumberOfTicks = 4; | |||
set(ax(1), 'ycolor', 'black', ... % Change right axis color to black | |||
'YTick', 0:recovery_rate_max/NumberOfTicks:recovery_rate_max); | |||
set(ax(2), 'ycolor', 'black', ... % Change left axis color to black | |||
'YTick', 0:(q_max+m_max)/NumberOfTicks:(q_max+m_max)); % | |||
ylim(ax(1), [0 recovery_rate_max]); | |||
ylim(ax(2), [0 q_max+m_max]); | |||
xlim([0 maxTime]); | |||
xlabel('Time, t, [s]'); | |||
ylabel(ax(1), 'Recovery rate [HP/s]'); | |||
ylabel(ax(2), 'Base Rate [HP/(max hp * s)]'); | |||
title('Leech Rate'); | |||
fig(3) = subplot(3,1,3); | |||
plot(t, hp_recovered_tot, 'b', t, hp_recovered_totVP, 'r-.'); | |||
ylim([0 inf]); | |||
xlim([0 maxTime]); | |||
xlabel('Time, t, [s]'); | |||
ylabel('HP recovered, [HP]'); | |||
title('HP recovered from leech'); | |||
legend('Recovery rate','Instantenous leech', 'Location','SouthEast') | |||
linkaxes(fig,'x') | |||
</pre>{{cob}} | |||
{{cot|Tab wide buyout creator. Last updated: 2016-03-08}}<pre> | |||
%% Tab wide buyout creator | |||
home; close all; clear all; | |||
% This script will create spoiler tab buyouts for use in shop | |||
% templates, for example in Procurement or Acquisition Plus. | |||
%% Input | |||
% File name to save the template to: | |||
fileName = 'Shop.txt'; | |||
% Price vector: | |||
minPrice = 0; priceIncrease = 0.5; maxPrice = 100; | |||
prices = minPrice:priceIncrease:maxPrice; | |||
% Define the name of spoiler and its stash name: | |||
% First column: Name of spoiler tag, can be Currency format, ilvl... | |||
% Second column: Shorthand stash name. | |||
currency = { | |||
'mirror', 'mirror', prices; | |||
'exa', 'ex', prices; | |||
'divine', 'divine', prices; | |||
'gcp', 'gcp', prices; | |||
'regal', 'regal', prices; | |||
'regret', 'regret', prices; | |||
'chaos', 'c', prices; | |||
'blessed', 'blessed', prices; | |||
'scour', 'scour', prices; | |||
'alchemy', 'alch', prices; | |||
'fuse', 'fuse', prices; | |||
'chisel', 'chis', prices; | |||
'chance', 'chance', prices; | |||
'jewel', 'jew', prices; | |||
'alt', 'alt', prices; | |||
'chrom', 'chrom', prices; | |||
'vaal', 'vaal', prices; | |||
'coin', 'coin', 0:10:30000; | |||
}; | |||
tag = '~b/o'; | |||
%% Print Shop | |||
% Open/create file to write: | |||
fileID = fopen(fileName,'w'); | |||
% Create buyouts for all the defined currencies in Currency: | |||
for currencyType = 1:length(currency(:, 1)) | |||
% Create spoiler buyouts for that particular currency type, | |||
% value according to Prices at the following form: | |||
for i = 1:length(currency{currencyType, 3}(1,:)); | |||
% For Procurement or pre-0.4 Acquisition Plus: | |||
% [spoiler="~b/o 2.5 mirror"] | |||
% {Stash:2.5mirror|include.ignored} | |||
% [/spoiler] | |||
% fprintf(fileID,'[spoiler="~b/o %g ', prices(i)); fprintf(fileID,currency{type,1}); fprintf(fileID,'"]'); | |||
% fprintf(fileID,'\n{Stash:%g', prices(i)); fprintf(fileID,currency{type,2}); fprintf(fileID,'|include.ignored}'); | |||
% fprintf(fileID,'\n[/spoiler]'); | |||
% fprintf(fileID,'\n'); | |||
% For 0.4+ Acquisition plus: | |||
% {Stash:1c|include.ignored|wrap|header:~b/o 1 chaos} | |||
fprintf(fileID,'{Stash:%g', currency{currencyType, 3}(1,i)); fprintf(fileID, currency{currencyType,2}); | |||
fprintf(fileID,'|include.ignored|wrap'); fprintf(fileID, '|header:'); | |||
fprintf(fileID, tag); fprintf(fileID, ' %g ', currency{currencyType, 3}(1,i)); | |||
fprintf(fileID, currency{currencyType,1}); fprintf(fileID, '}'); | |||
% fprintf(fileID,'\n'); | |||
end | |||
end | |||
% Close the written file: | |||
fclose(fileID); | |||
</pre>{{cob}} | |||
{{cot|Lucky vs. Normal rolls. Last updated: 2016-04-29}}<pre> | |||
%% Lucky vs. normal rolls | |||
close all, clear all, home | |||
%% Calculations | |||
% Chance to crit on the first roll: | |||
A = 0:1/100:1; | |||
% Chance to NOT crit on the first roll: | |||
B = 1 - A; | |||
% Chance to crit on the second roll: | |||
C = B .* A; | |||
% Chance to NOT crit on the second roll: | |||
D = B .* B; | |||
% The probability to get a lucky critical strike is the sum of A and C: | |||
LuckyCritChance = min(A + C, 1); | |||
%% Plot | |||
figure | |||
plot(100*A,100*A, 100*A,100*LuckyCritChance,'-.'); | |||
ylim(100*[0 1]) | |||
xlim(100*[0 max(A)]) | |||
title('Lucky vs. Normal rolls') | |||
legend('Default chance roll', 'Lucky chance roll', 'Location', 'Southeast') | |||
xlabel('[%]') | |||
ylabel('[%]') | |||
</pre>{{cob}} | |||
--- | |||
{{cob}} |
Latest revision as of 19:09, 15 March 2020
Subpages
Todo list
- Align passive skill tables with
{{Item table}}
by adding the parameters to pages using them: - Add option to remove column in item table if it's completely empty, relevant for
{{Area item drops}}
.
Scripts
Matlab scripts ▾
[Expand] ▾
Experience Penalty. Last updated: 2016-09-02 ▾
[Expand] ▾
%% Experience Penalty % The player also suffers a penalty to XP if the player is too far above % or below the monster's level. home, clear all, close all %% Input PlayerLevel = 1:100; %[30, 10]; MonsterLevel = 1:90; %% Calculations % Create a repeated matrix: mPlayerLevel = repmat(PlayerLevel, length(MonsterLevel), 1); mMonsterLevel = repmat(MonsterLevel, length(PlayerLevel), 1)'; % Minimum amount of experience penalty: minEXPMulti = 0.01; % There's a safe zone between player level and monster level where no % experience penalty is applied: SafeZone = floor(3 + mPlayerLevel/16); % Any additional level difference in excess of this safe range is the % effective level difference: EffectiveDifference = max(abs(mPlayerLevel - mMonsterLevel) - SafeZone, 0); % If the effective difference is negative that implies the player is inside % the safe zone. Therefore only values =>0 are relevant. % If the player level is outside the safe zone a multiplier on monsters % experience takes effect, reducing the amount. There are two penalties, % one at lower levels and one at higher levels. % Low levels: XPMultiplier_Low = ((mPlayerLevel + 5) ./ (mPlayerLevel + 5 + EffectiveDifference.^2.5)).^1.5; % High Levels: LevelThreshold = 95; BoolHighPenalty = mPlayerLevel >= LevelThreshold; XPMultiplier_High = (1 - 1 ./ (1 + 0.1 * (mPlayerLevel - 94))) .* BoolHighPenalty; XPMultiplier_High(isnan(XPMultiplier_High)) = 0; % Total penalty: XPMultiplier_Tot = max(XPMultiplier_Low .* (1 - XPMultiplier_High), minEXPMulti); %% Contour plot figure('position', [500, 500, 1100, 600]) [C,h] = contourf(mPlayerLevel, mMonsterLevel, XPMultiplier_Tot); ticks = 5; set(gca,'XTick',0:ticks:PlayerLevel(end)); set(gca,'YTick',0:ticks:MonsterLevel(end)); h = colorbar; h.Limits = [0.01 1]; grid minor shading interp title('Experience Penalty') xlabel('Player Level') ylabel('Monster Level') % zlabel('Experience efficiency') ylabel(h,'Experience Efficiency'); %% Party play % Parties with different character levels will gain different amount of % experience according to: PercentualShare = (PlayerLevel + 10).^2.71 ./ sum((PlayerLevel + 10).^2.71,2);
Chance to hit and avoid attacks. Last updated: 2015-12-10 ▾
[Expand] ▾
%% Chance to hit and avoid attacks. close all, clear all, home set(0,'DefaultFigureWindowStyle', 'docked'); % Sources: % http://pathofexile.gamepedia.com/Evasion % http://pathofexile.gamepedia.com/Accuracy %% Input step = 100; evasionRating = linspace(0, 50000, step); attackerAccuracy = linspace(0, 4000, step); chanceToDodge = 0; %% Calculations % Create a Mesh grid to be able to do contour plots: [evasionRatingMesh, attackerAccuracyMesh] = meshgrid(evasionRating, attackerAccuracy); % Chance to hit is a function if accuracy and evasion rating: chanceToHit = min(max( attackerAccuracyMesh ./ (attackerAccuracyMesh + (evasionRatingMesh/4).^0.8), 0.05) , 0.95); % Chance to avoid hits chanceToAvoidHit = 1 - chanceToHit*(1-chanceToDodge); %% Contour plot % Chance to avoid hit contour plot figure [C,h] = contourf(evasionRatingMesh,attackerAccuracyMesh,chanceToAvoidHit*100); clabel(C,h,'labelspacing',200) % clabel(C,h,'manual') colormap(cool) h = colorbar; h.Limits = [5 95]; grid minor shading interp title('Chance to avoid enemy attacks') xlabel('Defender''s Evasion Rating') ylabel('Attacker''s Accuracy Rating') ylabel(h,'Chance to avoid hit [%]'); % Chance to hit contour plot figure [C,h] = contourf(attackerAccuracyMesh,evasionRatingMesh, chanceToHit*100); clabel(C,h,'labelspacing',700) colormap(cool) h = colorbar; h.Limits = [5 95]; grid minor shading interp title('Chance to hit enemy') xlabel('Attacker''s Accuracy Rating') ylabel('Defender''s Evasion Rating') % zlabel('Experience efficiency') ylabel(h,'Chance to hit [%]');
Armour Reduction. Last updated: 2015-12-10 ▾
[Expand] ▾
%% Armour Reduction close all, clear all, home % Sources: % http://pathofexile.gamepedia.com/Armour %% Input step = 100; Armour = linspace(0, 50000, step); Damage = linspace(0, 10000, step); %% Calculations % Create a Mesh grid to be able to do contour plots: [ArmourMesh, DamageMesh] = meshgrid(Armour, Damage); Damage_Reduction_FactorMesh = ArmourMesh ./ (ArmourMesh + 10 * DamageMesh); %% Contour plot figure % [C,h] = contourf(ArmourMesh,DamageMesh,Damage_Reduction_FactorMesh*100); [C,h] = contour(ArmourMesh,Damage_Reduction_FactorMesh*100,DamageMesh, ... [100:200:600, 1000:500:2000, 3000:1000:6000, 8000:2000:10000]); clabel(C,h, 'labelspacing',700); clabel(C,h,'manual') colormap(copper) h = colorbar; % h.Limits = [0.01 1]; grid minor shading interp ylim([0 90]) title('Physical Damage Reduction when Hit') xlabel('Armour Rating') ylabel('#% additional Physical Damage Reduction when Hit') ylabel(h,'Raw Physical Damage');
Plot Energy shield recharge. Last updated: 2015-12-10 ▾
[Expand] ▾
%% Plot Energy shield recharge close all, clear all, home % Sources: % http://pathofexile.gamepedia.com/Energy_shield %% Inputs r = 0:300; BaseStart = 2; %% Calculations ESStartTime = BaseStart * 100./(100 + r); %% Plot figure plot(r, ESStartTime) title('Start of Energy Shield Recharge') xlabel('#% faster start of Energy Shield Recharge') ylabel('Start time of Energy Shield Recharge [s]') grid on
Leech Mechanics. Last updated: 2017-01-01 ▾
[Expand] ▾
%% Leech mechanics for Path of Exile % This script analyses how the leech rate changes with increasing number of % enemies and number of hits on the enemy. close all, clear all, home set(0,'DefaultFigureWindowStyle', 'docked'); %% Input hp = 5000; % Maximum Life/Mana. l = 0.05; % Damage Leeched as Life/Mana. m = 2.50; % increased Life/Mana Leeched per second. m_max = 0.15; % of maximum Life/Mana per second to % maximum Life/Mana Leech rate. % Damage values from the hit: damage = 500000/12; % Damage dealt. attacksPerSec = 12; % Attacks per Second. mobsPerAttack = 1; % Enemies hit by one attack. numberOfAttacks = 7; % Number of attacks done to enemies. % The time when the attack started: attackTime = 0:1/attacksPerSec:(numberOfAttacks - 1)/attacksPerSec; % The time when the attack hit the target(s): hitTime = kron(attackTime, ones(1,mobsPerAttack)); q = 0.02; % Base Leech Rate. q_max = 0.20; % Base Maximum Leech Rate. steps = 1000; % Number of steps. %% Calculations % Maximum recovery rate: recovery_rate_max = (q_max + m_max) * hp; % Leech duration: duration_i = floor(damage * l) / (hp *q) .* ones(1, length(hitTime)); % Total allowed leech instance to not exceed the maximum recovery rate: n_tot = (q_max + m_max) / (q * (1 + m)); % Maximum analysis time: maxTime = hitTime(end) + duration_i(end); % Time between each step: dt = (maxTime-0)/steps; % Repeat vectors: t = 0:dt:maxTime; tRep = repmat(t, length(hitTime), 1); instanceRep = repmat((1:length(hitTime))', 1, length(t)); AttackTimeRep = repmat(hitTime', 1, length(t)); durationRep = repmat(duration_i', 1, length(t)); % Boolean conditions to check if there have been an enemy hit and if % the leeched ife is lower than the total amount of life leeched. boolHitStart = tRep >= AttackTimeRep; boolLeechEnd = tRep < AttackTimeRep + durationRep; BoolLeechEndVP = tRep <= AttackTimeRep + dt*0.99; % Both of the above conditions must be true for leech to occur: boolLeech = (boolHitStart .* boolLeechEnd); boolLeechVP = (boolHitStart .* BoolLeechEndVP); % Base Recovery Rate for each leech instance: recovery_rate_i = hp * q * (1 + m) .* boolLeech; % Each active leech instance: leechInstance = instanceRep .* boolLeech; % Base Recovery Rate summarized for all the leech instances: recovery_rate_sum = sum(recovery_rate_i,1); % Check that r_sum is not greater than r_max: boolLimit = recovery_rate_sum >= recovery_rate_max; recovery_rate_sum = recovery_rate_max .* boolLimit ... + recovery_rate_sum .*(~boolLimit); % Pre-load for for-loop: hp_recovered_i = zeros(length(hitTime), length(t)); hp_recovered_tot = zeros(1, length(t)); hp_recovered_totVP = zeros(1, length(t)); for i = 1:length(t)-1; % HP restored from each leech instance, this is used to check % when each leech instance is finished: hp_recovered_i(:,i+1) = q * hp .* boolLeech(:,i) * dt ... + hp_recovered_i(:,i); % Total HP restored from all the leech instances: hp_recovered_tot(:,i+1) = recovery_rate_sum(:,i) * dt ... + hp_recovered_tot(:,i); % Vaal Pact restores life instanteously: hp_recovered_totVP(:,i+1) = damage * l .* sum(boolLeechVP(:,i),1) ... + hp_recovered_totVP(:,i); end %% Plot figure leechInstance(leechInstance == 0) = NaN; % Remove zeros from plot. fig(1) = subplot(3,1,1); colororder = get(gca,'colororder'); plot(t, leechInstance, 'Color', colororder(1,:)); % set(gca, 'YTick', 0:length(hitTime)); % Show integers only. ylim([0 length(hitTime)+0.5]); xlim([0 maxTime]); xlabel('Time, t, [s]'); ylabel('Leech instance'); title('Leech instance'); for i = 1:length(hitTime); hold on % Find the start and end point of each instance and mark it: [rowStart, colStart] = find(~isnan(leechInstance(i,:)), 1, 'first'); [rowEnd, colEnd] = find(~isnan(leechInstance(i,:)), 1, 'last'); plot(t(colStart), leechInstance(i, colStart), 'b.', ... t(colEnd), leechInstance(i, colEnd),'bx', ... t(colStart), leechInstance(i, colStart),'ro'); % Vaal Pact Start and End: plot(t(colStart), leechInstance(i, colStart),'ro'); end fig(2) = subplot(3,1,2); [ax, h1, h2] = plotyy(t, recovery_rate_sum, t, recovery_rate_sum/hp); delete(h2); NumberOfTicks = 4; set(ax(1), 'ycolor', 'black', ... % Change right axis color to black 'YTick', 0:recovery_rate_max/NumberOfTicks:recovery_rate_max); set(ax(2), 'ycolor', 'black', ... % Change left axis color to black 'YTick', 0:(q_max+m_max)/NumberOfTicks:(q_max+m_max)); % ylim(ax(1), [0 recovery_rate_max]); ylim(ax(2), [0 q_max+m_max]); xlim([0 maxTime]); xlabel('Time, t, [s]'); ylabel(ax(1), 'Recovery rate [HP/s]'); ylabel(ax(2), 'Base Rate [HP/(max hp * s)]'); title('Leech Rate'); fig(3) = subplot(3,1,3); plot(t, hp_recovered_tot, 'b', t, hp_recovered_totVP, 'r-.'); ylim([0 inf]); xlim([0 maxTime]); xlabel('Time, t, [s]'); ylabel('HP recovered, [HP]'); title('HP recovered from leech'); legend('Recovery rate','Instantenous leech', 'Location','SouthEast') linkaxes(fig,'x')
Tab wide buyout creator. Last updated: 2016-03-08 ▾
[Expand] ▾
%% Tab wide buyout creator home; close all; clear all; % This script will create spoiler tab buyouts for use in shop % templates, for example in Procurement or Acquisition Plus. %% Input % File name to save the template to: fileName = 'Shop.txt'; % Price vector: minPrice = 0; priceIncrease = 0.5; maxPrice = 100; prices = minPrice:priceIncrease:maxPrice; % Define the name of spoiler and its stash name: % First column: Name of spoiler tag, can be Currency format, ilvl... % Second column: Shorthand stash name. currency = { 'mirror', 'mirror', prices; 'exa', 'ex', prices; 'divine', 'divine', prices; 'gcp', 'gcp', prices; 'regal', 'regal', prices; 'regret', 'regret', prices; 'chaos', 'c', prices; 'blessed', 'blessed', prices; 'scour', 'scour', prices; 'alchemy', 'alch', prices; 'fuse', 'fuse', prices; 'chisel', 'chis', prices; 'chance', 'chance', prices; 'jewel', 'jew', prices; 'alt', 'alt', prices; 'chrom', 'chrom', prices; 'vaal', 'vaal', prices; 'coin', 'coin', 0:10:30000; }; tag = '~b/o'; %% Print Shop % Open/create file to write: fileID = fopen(fileName,'w'); % Create buyouts for all the defined currencies in Currency: for currencyType = 1:length(currency(:, 1)) % Create spoiler buyouts for that particular currency type, % value according to Prices at the following form: for i = 1:length(currency{currencyType, 3}(1,:)); % For Procurement or pre-0.4 Acquisition Plus: % [spoiler="~b/o 2.5 mirror"] % {Stash:2.5mirror|include.ignored} % [/spoiler] % fprintf(fileID,'[spoiler="~b/o %g ', prices(i)); fprintf(fileID,currency{type,1}); fprintf(fileID,'"]'); % fprintf(fileID,'\n{Stash:%g', prices(i)); fprintf(fileID,currency{type,2}); fprintf(fileID,'|include.ignored}'); % fprintf(fileID,'\n[/spoiler]'); % fprintf(fileID,'\n'); % For 0.4+ Acquisition plus: % {Stash:1c|include.ignored|wrap|header:~b/o 1 chaos} fprintf(fileID,'{Stash:%g', currency{currencyType, 3}(1,i)); fprintf(fileID, currency{currencyType,2}); fprintf(fileID,'|include.ignored|wrap'); fprintf(fileID, '|header:'); fprintf(fileID, tag); fprintf(fileID, ' %g ', currency{currencyType, 3}(1,i)); fprintf(fileID, currency{currencyType,1}); fprintf(fileID, '}'); % fprintf(fileID,'\n'); end end % Close the written file: fclose(fileID);
Lucky vs. Normal rolls. Last updated: 2016-04-29 ▾
[Expand] ▾
%% Lucky vs. normal rolls close all, clear all, home %% Calculations % Chance to crit on the first roll: A = 0:1/100:1; % Chance to NOT crit on the first roll: B = 1 - A; % Chance to crit on the second roll: C = B .* A; % Chance to NOT crit on the second roll: D = B .* B; % The probability to get a lucky critical strike is the sum of A and C: LuckyCritChance = min(A + C, 1); %% Plot figure plot(100*A,100*A, 100*A,100*LuckyCritChance,'-.'); ylim(100*[0 1]) xlim(100*[0 max(A)]) title('Lucky vs. Normal rolls') legend('Default chance roll', 'Lucky chance roll', 'Location', 'Southeast') xlabel('[%]') ylabel('[%]')
---