Repository navigation
Loot Generation
The Item class provides the base structure for items in the loot generation system.
Each item has:
- A unique ID
- A name
- An item type
- A quantity
- A maximum quantity
The ItemType enum contains the following item types:
CONSUMABLEWEAPONCURRENCY
The item quantity is limited between 0 and the maximum quantity.
The setQuantity() method prevents the quantity from going above the maximum quantity or below 0.
The addQuantity() method increases the item quantity while keeping it within the allowed range.
The isStackFull() method checks whether the item has reached its maximum quantity.
The isEmpty() method checks whether the item quantity is 0.
The Item constructor validates:
- The item name cannot be null or blank.
- The item type cannot be null.
- The maximum quantity must be greater than
0.
Invalid values result in an IllegalArgumentException.
ItemTest verifies:
- Item creation and properties
- Unique IDs
- Quantity limits
- Adding quantity
- Maximum quantity limits
- Full stack detection
- Empty stack detection
- Invalid maximum quantity
- Blank item names
- Null item types
- All three item types
The Currency Item introduces gold as an in-game currency and adds a visible Gold Coin entity to the game world. Gold is managed through InventoryComponent, while the coin itself is created using GoldCoinFactory.
-
GoldCoinFactorycreates the Gold Coin entity and attaches anAnimationRenderComponent. - The coin uses
gold_coin.atlasfor a spinning animation . -
ForestGameArealoads the Gold Coin assets and spawns a coin at the center. -
InventoryComponentmanages the player's gold balance. -
InventoryComponentTesttests the currency management functionality.
The Gold Coin is created and spawned in the game world, and the player's gold balance can be managed through the inventory system. The connection between collecting the physical coin and automatically adding gold to the inventory is being handled by another team.
This feature implements weapon items and weapon generation for the game. It supports different weapon types, damage values, weapon assets, and basic playable weapon functionality.
WeaponItem extends the existing item structure with weapon-specific properties:
- Weapon type
- Damage value
The currently implemented weapon types are:
- SWORD
- BOW
WeaponGenerator generates weapon items based on their weapon type and level. This allows weapons to be generated consistently and used with other game systems.
Assets were added for the implemented weapons and projectile:
images/sword.pngimages/bow.pngimages/arrow.png
The sword is rendered with the player and supports basic attack behaviour using the weapon's damage value.
The bow supports ranged attacks by creating an arrow projectile. The projectile travels through the game world in the attack direction.
A basic weapon display was added to show the player's equipped weapon and its damage value.
Example:
Weapon: Sword
Damage:
Generated swords and bows can be spawned as weapon loot in the game area. This demonstrates that generated WeaponItem objects can be integrated with the game's loot system.
The implementation was tested using Gradle and manual in-game testing.
Gradle commands used:
.\gradlew.bat test
.\gradlew.bat spotlessCheck
In-game testing included weapon generation, sword attacks, bow functionality, projectile movement, weapon rendering, and weapon loot spawning.
Consumable items are items the player can use for an immediate effect. There are three of them:
| Consumable | Sprite | Effect |
|---|---|---|
| Health Potion | Health.png |
Restores health, up to the player's maximum |
| Damage Potion | Poison.png |
Multiplies attack damage for a set time, then reverts |
| Speed Potion | Strength.png |
Multiplies movement speed for a set time, then reverts |
ConsumableItem extends Item, in the same way WeaponItem does, and adds two properties:
-
consumableType- which consumable it is -
effect- what happens when it is used
All consumables have the item type ItemType.CONSUMABLE. Each one also carries its own sprite, so
nothing else has to look up a texture:
ConsumableType.HEALTH_POTION.getTexturePath(); // "images/Health.png"Rather than one class deciding every behaviour with a switch, each item holds an effect object.
HealEffect restores health and BuffEffect starts a timed stat change. Adding a new consumable
later means writing a new effect class, not editing an existing one.
ConsumableUseComponent is added to the player and listens for a useItem event carrying an
inventory slot number:
entity.getEvents().trigger("useItem", slot);An effect reports whether it actually did anything, and the item is only removed if it did. So a health potion used at full health has no effect and stays in the inventory.
"useItem" is triggered with a slot
↓
ConsumableUseComponent reads that slot from the inventory
↓
The item's effect is applied
↓
Did the effect do anything?
↓ yes ↓ no
One is removed from the stack The item is left alone
PlayerBuffComponent applies temporary stat changes and reverts them on its own. It uses the
GameTime service, the same way WaitTask does, so there is no separate timer in the codebase.
It remembers the player's normal stats when it is created, then sets each buffed stat to its normal value multiplied by every active buff. Starting a buff and ending one both use that same rule, so overlapping buffs work and nothing drifts.
Buff state can be read from outside, so a buff timer UI can be added later:
-
buffAppliedandbuffExpiredevents, each carrying theActiveBuff -
getActiveBuffs()for the current list -
ActiveBuff.getRemainingSeconds(currentTime)for a countdown
Heal amount, buff strength and duration are stored in configs/consumables.json and loaded into
ConsumableConfig / ConsumableConfigs, following the same pattern as NPCConfigs. Values are not
hardcoded.
ConsumableGenerator builds an item at a given loot tier, matching WeaponGenerator:
ConsumableItem potion =
new ConsumableGenerator().generateConsumable(ConsumableType.HEALTH_POTION, 2);Healing multiplies by tier. For buffs, only the part above 1.0 grows, so a configured 1.5x becomes 2.0x at tier 2. Items above tier 1 get a tier in their name, because the inventory stacks items by name and a weak potion should not merge with a strong one.
Consumables are dropped and collected through the existing LootFactory, the same as weapons, so
walking over one adds it to the inventory. They are drawn with BobbingTextureRenderComponent,
which floats the sprite up and down so a dropped item reads as collectable. The float is applied
when drawing rather than by moving the entity, so the pickup area stays where the item was placed.
The loot generation system was connected to the inventory so that the items created in the game can actually be collected and stored by the player.
When a loot item is created, it is attached to the loot entity using LootPickupComponent. When the player touches the loot, the item is passed to the player's InventoryComponent.
This works for the different item types used in the game:
- Weapons such as swords and bows are added to the inventory.
- Consumables such as potions are added to the inventory with their quantity.
- Currency such as gold coins is added to the player's stored gold.
The basic flow is:
Loot is generated
↓
LootFactory creates the loot entity
↓
LootPickupComponent handles the pickup
↓
Player touches the loot
↓
InventoryComponent receives the item
↓
Item is stored in the inventory
The loot generation and inventory connection was tested by running the game and checking each type of generated loot.
- Run the game and enter the Forest area.
- Locate the generated coins, weapons and consumable items.
- Move the player over each item to pick it up.
- Check that the item disappears from the game world after being collected.
- Open the player's inventory and check that the collected item has been added.
- Repeat this for coins, weapons and consumable items to confirm that all loot types are correctly connected to the Inventory system.
Coins, weapons and consumable items should all be collectible by the player. After being collected, each item should be stored correctly in the player's inventory.