-
Notifications
You must be signed in to change notification settings - Fork 14
RPG Library: Items
RPGs have a lot of items, from magic weapons, to cursed rings.
Go here for the introduction to RPG.
Any item (or character) can have an "activeEffects" attribute that is a list of strings. Each entry should be the name of an effect. Thus, an item can have any number of effects at one time, and more can be added or removed as the game progresses.
An active effect will apply to the player as long as an item is held, however you can modify the effect to make it selective. For example, for an effect for a weapon, you might want to have the "modifyOutgoingAttack" function check that the item is equipped; for armour, you might want to have the "modifyIncomingAttack" function check that the item is worn.
Use this template for weapons, obviously; it needs the damage as a string. For example:
createItem("knife", WEAPON("d4+2"), {
loc:"me",
offensiveBonus:1,
});
The important attributes are:
loc: The name of the location as usual.
offensiveBonus: A bonus (or penalty) to the hit roll (defaults to zero).
element: A weapon can be associated with an element; gives increased or decreased damage against some foes (defaults to none).
modifyOutgoingAttack: A weapon can change any of the parameters of the attack though this function. Unlike the "activeEffects", this will only apply if the weapon is used in the attack.
damageType: You may want to specify the type of damage a weapon does, to allow different enemies to have vulnerabilites. For example, skeletons might only take damage from crushing weapons. The suggested types are Slash, Bash, Pierce and Axe.
weaponClass: You may want to specify the class of a weapon, for example to allow different spells to affect different weapons. The suggested types are Blade, Crushing, Firearm, Bow, Thrown, Axe and Polearm.
For weapons that take ammo, use the LIMITED_USE_WEAPON template instead, which also requires the initial ammo.
createItem("shotgun", LIMITED_USE_WEAPON("4d4", 1), {
loc:"practice_room",
});
The rpg/weapons.js file can be used to add 30 weapon prototypes, and a good approach is to simply clone these. You should add descriptions.
const orc_chief_axe = cloneObject(w.great_axe_prototype, 'orc_chief')
orc_chief_axe.examine = 'This axe is huge. Crudely made, it still looks pretty viscious.'
A template for shields. Like weapons, shields have to be equipped. Has a built-in "modifyIncomingAttack" attribute. You could modify it for special effects, but it is probably better to add special effects using "activeEffects" (have the effect check if the shield is equipped).
createItem("target shield", SHIELD(2), {
loc:"me",
});
The parameter is the defensive bonus; this number will be deducted from the "to hit" roll (so works very differently to armour, which reduces damage).
Makes a spell book from a list of spell names.
createItem("spellbook", SPELLBOOK(["Fireball", "Stoneskin"]), {
loc:"practice_room",
});
The player can then LEARN FIREBALL, etc. as long as she holding the book.
A SPELLFONT is the same, except it cannot be picked up, and therefore does not need to be held to learn the spells.
Both use their "spellsAvailableToLearn" attribute to store the spells available, as a string list, and this can be modified during play if desired.
There is no template for armour; armour is any WEARABLE with an "armour" attribute.
createItem("helmet", WEARABLE(2, ['head']), {
loc:"practice_room",
armour:10,
});
The armour of the player is the total armour of all she is wearing divided by 10 (modify settings.armourScaling
to change). This means the helmet in the example gives +1 to the player's armour, which is quite significant under the default rules. I would suggest ensuring the player does not get much more than 50 armour total (i.e., +5 armour bonus) even at high level, as that will stop so much damage. Ration out appropriately! That said, chest and head armour should be proportionally more as these are more vital areas. Armour that covers more of the body should also have a higher armour value.
You really need to set armour to have a layer and slots to prevent the player wearing, say, fourteen helmets. See the WEARABLE template for details on that.
You can make a wearable magic item in two ways - either have it do something when the item is put on or removed, or give it a function to modify attacks. This example does the former.
createItem("agility_amulet", WEARABLE(4, ['neck']), {
examine:"An example of a wearable magic item; it raises agility by 5.",
afterWear:function(options) {
options.char.agility += 5
},
afterRemove:function(options) {
options.char.agility -= 5
},
})
The AMULET template is just a WEARABLE with the slots done for you; just as for the above example, it will fill slot "amulet" at layer 0. This amulet illustrates how a magic item can modify an incoming attack.
createItem("ice_amulet", AMULET(), {
examine:"An example of a wearable magic item; it stops ice/frost damage.",
modifyIncomingAttack:function(attack) {
if (this.worn && attack.element === 'frost') {
attack.damageMultiplier = 0
attack.primarySuccess = attack.primarySuccess.replace(/[.!]/, ", but the ice amulet protects {sb:target}, and {pv:target:take} no damage.")
}
}
})
Rings are slightly different to wearables because a character can wear more than one. The number is determined by their "maxNumberOfRings" attribute, which defaults to two, but you could argue a character can wear up to ten, or even twenty if you allow toes as well.
createItem("blue_ring", RING(), {
loc:"me",
worn:true,
examine:"A fancy blue ring.",
})
Note that behind the scenes rings use the WEARABLE template (but without a slot or layer). If you want to restrict when a ring can be worn using "testWorn" you will need to include the existing code.
testWear:function(options) {
if (!this.testWearForRing(options)) return false
// your tests here
return true
},
These are one-off items - after use, the item is gone. They are created by giving the template the name of a spell. In my view, potions should only cast spells on the person drinking it, while scrolls can be used to cast any spell; it is necessary therefore, to tell Quest if this scroll-spell needs a target.
createItem("pink_scroll", SCROLL("Fireball", false), {
examine:'A scroll with a magical glyph on it.',
identify:'Contains the spell "Fireball".',
})
createItem("blue_scroll", SCROLL("Ice shard", true), {
examine:'A scroll with a magical glyph on it.',
identify:'Contains the spell "Ice shard".',
})
createItem("healing_potion", POTION("Healing"), {
examine:'A sweet smelling concoction!',
})
I would suggest you have some way for the player to determine what a potion or scroll does. In the examples above, the healing potion is obvious. The scrolls can be identified with the "Identify" spell, as they have an "identify" attribute. You could add hints, like the scroll feels warm or cold.
Tutorial
- First steps
- Rooms and Exits
- Items
- Templates
- Items and rooms again
- More items
- Locks
- Commands
- Complex mechanisms
- Uploading
QuestJS Basics
- General
- Settings
- Attributes for items
- Attributes for rooms
- Attributes for exits
- Naming Items and Rooms
- Restrictions, Messages and Reactions
- Creating objects on the fly
- String Functions
- Random Functions
- Array/List Functions
- The
respond
function - Other Functions
The Text Processor
Commands
- Introduction
- Basic commands (from the tutorial)
- Complex commands
- Example of creating a command (implementing SHOOT GUN AT HENRY)
- More on commands
- Shortcut for commands
- Modifying existing commands
- Custom parser types
- Note on command results
- Meta-Commands
- Neutral language (including alternatives to "you")
- The parser
- Command matching
Templates for Items
- Introduction
- Takeable
- Openable
- Container and surface
- Locks and keys
- Wearable
- Furniture
- Button and Switch
- Readable
- Edible
- Vessel (handling liquids)
- Components
- Countable
- Consultable
- Rope
- Backscene (walls, etc.)
- Merchandise (including how to create a shop)
- Shiftable (can be pushed from one room to another)
See also:
- Custom templates (and alternatives)
Handing NPCs
- Introduction
- Attributes
- Allowing the player to give commands
- Conversations
- Simple TALK TO
- SAY
- ASK and TELL
- Dynamic conversations with TALK TO
- Following an agenda
- Reactions
- Giving
- Followers
- Changing the player point-of-view
The User Experience (UI)
The main screen
- Basics
- Printing Text Functions
- Special Text Effects
- Output effects (including pausing)
- Hyperlinks
- User Input
The Side Panes
Multi-media (sounds, images, maps, etc.)
- Images
- Sounds
- Youtube Video (Contribution by KV)
- Adding a map
- Node-based maps
- Image-based maps
- Hex maps
- Adding a playing board
- Roulette!... in a grid
Dialogue boxes
- Character Creation
- Other example dialogs [See also "User Input"]
Other Elements
- Toolbar (status bar across the top)
- Custom UI Elements
Role-playing Games
- Introduction
- Getting started
- Items
- Characters (and Monsters!)
- Attributes for characters
- Attacking and guarding
- Skills and Spells
- Limiting Magic
- Effects
- The Attack Object
- Quests for Quest
- User Interface
Web Basics
- HTML (the basic elements of a web page)
- CSS (how to style web pages)
- SVG (scalable vector graphics)
- Colours
- JavaScript
- Regular Expressions
How-to
Time
- Events (and Turnscripts)
- Date and Time (including custom calendars)
- Timed Events (i.e., real time, not game time)
Items
- Phone a Friend
- Using the USE verb
- Display Verbs
- Change Listeners
- Ensembles (grouping items)
Locations
- Large, open areas
- Region,s with sky, walls, etc.
- Dynamic Room Descriptions
- Transit system (lifts/elevators, buses, trains, simple vehicles)
- Rooms split into multiple locations
Exits
- Alternative Directions (eg, port and starboard)
- Destinations, Not Directions
Meta
- Customise Help
- Provide hints
- Include Achievements
- Add comments to your code
-
End The Game (
io.finish
)
Meta: About The Whole Game
- Translate from Quest 5
- Authoring Several Games at Once
- Chaining Several Games Together
- Competition Entry
- Walk-throughs
- Unit testing
- Debugging (trouble-shooting)
Releasing Your Game
Reference
- The Language File
- List of settings
- Scope
- The Output Queue
- Security
- Implementation notes (initialisation order, data structures)
- Files
- Code guidelines
- Save/load
- UNDO
- The editor
- The Cloak of Darkness
- Versions
- Quest 6 or QuestJS
- The other Folders
- Choose your own adventure