forked from nounsDAO/nouns-monorepo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNounsSeeder.sol
83 lines (63 loc) · 2.87 KB
/
NounsSeeder.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// SPDX-License-Identifier: GPL-3.0
/// @title The NounsToken pseudo-random seed generator
pragma solidity ^0.8.6;
import 'hardhat/console.sol';
import { INounsSeeder } from './interfaces/INounsSeeder.sol';
import { INounsDescriptor } from './interfaces/INounsDescriptor.sol';
contract NounsSeeder is INounsSeeder {
/**
* @notice Generate a pseudo-random Nouns seed using the previous blockhash and nouns ID.
*/
function generateSeed(uint256 nounId, INounsDescriptor descriptor) external view override returns (Seed memory) {
uint256 pr = uint256(keccak256(abi.encodePacked(blockhash(block.number - 1), nounId)));
INounsDescriptor.AttributeRanges memory ranges = descriptor.getAttributeRanges();
INounsSeeder.Seed memory seed;
seed.volumeCount = randomUint8InRange(pr >> (16 * 0), ranges.volumeCountRange[0], ranges.volumeCountRange[1]);
seed.maxVolumeHeight = randomUint8InRange(
pr >> (16 * 1),
ranges.maxVolumeHeightRange[0],
ranges.maxVolumeHeightRange[1]
);
seed.waterFeatureCount = randomUint8InRange(
pr >> (16 * 2),
ranges.waterFeatureCountRange[0],
ranges.waterFeatureCountRange[1]
);
seed.grassFeatureCount = randomUint8InRange(
pr >> (16 * 3),
ranges.grassFeatureCountRange[0],
ranges.grassFeatureCountRange[1]
);
seed.treeCount = randomUint8InRange(pr >> (16 * 4), ranges.treeCountRange[0], ranges.treeCountRange[1]);
seed.bushCount = randomUint8InRange(pr >> (16 * 5), ranges.bushCountRange[0], ranges.bushCountRange[1]);
seed.peopleCount = randomUint8InRange(pr >> (16 * 6), ranges.peopleCountRange[0], ranges.peopleCountRange[1]);
seed.timeOfDay = randomUint8InRange(pr >> (16 * 7), ranges.timeOfDayRange[0], ranges.timeOfDayRange[1]);
seed.season = randomUint8InRange(pr >> (16 * 8), ranges.seasonRange[0], ranges.seasonRange[1]);
seed.greenRooftopP = randomUint8InRange(
pr >> (16 * 9),
ranges.greenRooftopPRange[0],
ranges.greenRooftopPRange[0]
);
seed.siteEdgeOffset = randomUint256InRange(
pr >> (16 * 10),
ranges.siteEdgeOffsetRange[0],
ranges.siteEdgeOffsetRange[1]
);
seed.orientation = randomUint256InRange(pr >> (16 * 11), ranges.orientationRange[0], ranges.orientationRange[1]);
return seed;
}
function randomUint8InRange(
uint256 randomValue,
uint8 min,
uint8 max
) internal pure returns (uint8 value) {
return uint8(randomUint256InRange(randomValue, min, max));
}
function randomUint256InRange(
uint256 randomValue,
uint256 min,
uint256 max
) internal pure returns (uint256 value) {
return (randomValue % (max - min + 1)) + min;
}
}