Scripting
The scripting language used by SWC is currently available for speeches of Custom NPCs and for interactions with items (e.g. egg incubator).
The new language (SWC Lisp) is a big step ahead from the old system. Here we want to list the major differences with the old system to ease the conversion from the old system to the new one.
Wildcards
SWC Lisp | Old Wildcard | Description | Example | Default | For Custom NPCs? |
---|---|---|---|---|---|
(get-name self) | %npc.name% | NPC's name | Joe Bloggs | N/A | Yes |
(get-race self) | %npc.race% | NPC's race | Nautolan | N/A | Yes |
(get-infofield self) | %npc.infofield% | NPC's infofield | Master Carpenter | N/A | Yes |
(get-gender self) | %npc.gender% | NPC's gender | Male | N/A | Yes |
(get-formal self) | %npc.formal% | NPC's formal greeting | Sir/Ma'am | N/A | Yes |
(is-ally? self) | %npc.ally% | is NPC IFF friendly? | N/A | N/A | Yes |
(is-enemy? self) | %npc.enemy% | is NPC IFF enemy? | N/A | N/A | Yes |
(is-neutral? self) | %npc.neutral% | is NPC IFF neutral? | N/A | N/A | Yes |
(is-unharmed? self) | %npc.unharmed% | is NPC unharmed? | N/A | N/A | Yes |
(is-slightly-wounded? self) | %npc.slightlywounded% | is NPC slightly wounded? | N/A | N/A | Yes |
(is-wounded? self) | %npc.wounded% | is NPC wounded? | N/A | N/A | Yes |
(is-badly-wounded? self) | %npc.badlywounded% | is NPC badly wounded? | N/A | N/A | Yes |
(get-name character) | %character.name% | Character's handle | Selatos | N/A | Yes |
(get-race character) | %character.race% | Character's race | Human | N/A | Yes |
(get-infofield character) | %character.infofield% | Character's 1st infofield | Emperor | Empty String | Yes |
(get-infofield2 character) | %character.infofield2% | Character's 2nd infofield | 1st Recon Division | Empty String | Yes |
(get-infofield3 character) | %character.infofield3% | Character's 3rd infofield | 2nd Expansionary Fleet | Empty String | Yes |
(get-gender character) | %character.gender% | Character's gender | Male | N/A | Yes |
(is-unharmed? character) | %character.unharmed% | is Character unharmed? | N/A | N/A | Yes |
(is-slightly-wounded? character) | %character.slightlywounded% | is Character slightly wounded? | N/A | N/A | ]Yes |
(is-wounded? character) | %character.wounded% | is Character wounded? | N/A | N/A | Yes |
(is-badly-wounded? character) | %character.badlywounded% | is Character badly wounded? | N/A | N/A | Yes |
(get-formal character) | %character.formal% | Character's formal greeting | Sir/Ma'am | N/A | Yes |
(get-entity-faction) | %character.faction% | Character's current faction | New Republic | Freelance | Yes |
(is-owner? character) | %character.isowner% | Is character the owner of the NPC | Produces no output | Empty String | Yes |
(is-manager? character) | %character.ismanager% | Is character the manager of the NPC | Produces no output | Empty String | Yes |
(is-pilot? character) | %character.issupervisor% | Is character the owner of the NPC | Produces no output | Empty String | Yes |
(get-name (get-entity-faction character)) | %faction.name% | Character's faction's name | New Republic | Empty string (if freelance) | Yes |
(is-freelance? character) | n.a. | Checks if character's freelance | Yes | ||
(faction-type (get-faction character)) | %faction.type% | Character's faction's type | Mining | Empty string (if freelance) | Yes |
(faction-leader (get-faction character)) | %faction.leader% | Character's faction's leaders name | Ellias | Empty String (if freelance) | Yes |
(faction-website (get-faction character)) | %faction.website% | Character's faction's leaders name | http://swcombine.com (Link) | Empty string (if freelance) | Yes |
%owner.name% | Name of the NPC's owner | Darkness | Empty string if special owner (Market, None) | Yes | |
%owner.entityType% | Type of the NPC's owner | Faction or Character | Empty string if special owner (Market, None) | Yes | |
%owner.infofield% | Owner's 1st infofield | Emperor | Empty String | Yes | |
%owner.infofield2% | Owner's 2nd infofield | 1st Recon Division | Empty String | Yes | |
%owner.infofield3% | Owner's 3rd infofield | 2nd Expansionary Fleet | Empty String | Yes | |
(city-name character) | %location.city% | Current city name | City 327 | Unknown | Yes* |
(planet-name character) | %location.planet% | Current planet name | Glee Anselm | Unknown | Yes* |
(system-name character) | %location.system% | Current system name | Danju | Unknown | Yes* |
(sector-name character) | %location.sector% | Current sector name | Tapani | Unknown | Yes* |
%location.destination% | Destination name | "Corellia sector" (if deep space) "Corellia system" (if heading to that system) "Corellia planet" (if heading in sublight) | |||
%location.eta% | ETA for current travel | 3 days, 24 hours and 5 minutes | Unknown | Yes* | |
(is-traveling? character) | n.a. | Checks if the character is traveling or not | Yes | ||
(get-name (get-container self)) | %container.name% | Current container name, e.g. the ship or vehicle standing in | Tydirium | Unknown | Yes |
%container.type% | Current container type, e.g. the ship or vehicle standing in | Lambda Shuttle | Unknown | Yes | |
(get-entity-type entity-object) | %container.entityType% | Current container entity type, e.g. the ship, vehicle, city, planet, station | Ship, Vehicle, City, Planet, Space Station | N/A | Yes |
(in-room? entity-object) | n.a. | Checks if the entity is in any room at all, as opposed to outside on the surface | Yes | ||
cgt-year | %cgt.year% | Gets current CGT year | 12 | N/A | Yes |
cgt-day | %cgt.day% | Gets current CGT day | 183 | N/A | Yes |
cgt-hour | n.a. | Gets current CGT hour | 23 | N/A | Yes |
cgt-minute | n.a. | Gets current CGT minutes | 59 | N/A | Yes |
timeofday | %time.ofday% | Gets current phase of day | Morning, Afternoon, Evening | N/A | Yes |
Entries with a "Yes" are available for custom NPCs. Entries with a "Yes*" may have some limitations on their use (e.g. they may not be available when the NPC cannot reliably determine the information without godmodding - for example location whilst in hyperspace).
Conditional Statements
The biggest differences are:
- the "=" is no longer used to do comparisons;
Old system:
!if character.race=Gungan! Don't slip over! !if character.race=Human! Humans are the best! !ifnot character.race=Human! Alien scum!
New system:
(cond [(eq? (get-race character) "Gungan") (say "Don't slip over!") (say "Alien scum!")] [(eq? (get-race character) "Human") (say "Humans are the best!")] [#t (say "Alien scum!")])
OR
(cond[(eq? (get-race character) "Gungan") (say "Don't slip over!") (say "Alien scum!")]) (cond [(is-owner?) (say "Oh, uh. Welcome Boss!")]
- with cond statement, the conditions are tested sequentially until one of them is true, and then it evaluates it and stops testing. This is much like an If...ElseIf...ElseIf. This means that if you have two statements, you must put them inside the same condition. If you have multiple alternate conditions (ElseIfs) to test, you must ensure that at least one of them evaluates true every time. Commonly this is done with a final [#t] condition.
- You can use cond statements as a simple IF by only including one test.
Old system:
Responses: !if character.race=Baragwin! !if character.gender=Female! Excuse me, how do you know I am a female? -> Baragwin female !if character.race=Baragwin! !if character.gender=Male! Excuse me, how do you know I am a male? -> Baragwin male !ifnot character.race=Baragwin! I'd like to have more information on the museum. -> info !ifnot character.race=Baragwin! What can I do here? -> what to do !ifnot character.race=Baragwin! Do I need to pay an entrance fee? -> fee
New system:
(cond [(and (eq? (get-race character) "Baragwin") (eq? (get-gender character) "Female")) (add-response "Excuse me, how do you know I am a female?" Baragwin-female)] [(and (eq? (get-race character) "Baragwin") (eq? (get-gender character) "Male")) (add-response "Excuse me, how do you know I am a male?" Baragwin-male)] [(not (eq? (get-race character) "Baragwin")) (add-response "I'd like to have more information on the museum." info) (add-response "What can I do here?" what-to-do) (add-response "Do I need to pay an entrance fee?" fee)]))
Public Functions
- get-hp-status-text
- get-character
- get-id
- get-faction
- trim
- rand-from-list
Conversation
Syntax | Example of Use | Actual Output |
---|---|---|
say string | (say "Hello World!") | "Hello World!" |
describe string | (describe "The droid beeps and burps.") | The droid beeps and burps. |
ooc string | (ooc "Now go to the mentioned location and talk to the NPC there.") | |
add-response string next-function) | (add-response "Wow, I didn't know that!" explainmore) | say "Wow, I didn't know that!" |
add-action string next-function | (add-action " exit the room." room12) | You exit the room. |
Admin-Only Functions
- is-force-aware?
- get-skill
- get-force-skill
Admin scripts now have xvars and yvars which allow arbitrary context pairs (superseding q, o, t, e, etc. vars).
User scripts still have s-, o-, and e- vars
- *vars can now properly handle lists of values in addition to scalar values. Storing an instance of a class is not supported and (should) result in an exception being thrown.
Debugging Functions
- dbg-break added to trigger an exception (ignoring the rest of the script) and print supplied values, for example (dbg-break self character (+ 1 2)) will display info about the current entity, current character, and the number 3
- dbg-pp added to print values for debugging without triggering an exception (script continues), using the same semantics as dbg-break
- dbg-env added, which dumps the entire symbol table (very large) and can be used to get basic information about the API to help with missing documentation