User:Illviljan

Todo list

 * Align passive skill tables with 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.

Scripts
%% 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. 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 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 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 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 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 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('[%]')

---