// Includes some definitions
#include "_macros.fos"
// Function signature for player interactions with Scenery objects
bool s_RefillRobot(Critter& player, Scenery& robot, int skill, Item@ item)
{
// Retrieve the variable used by the quest to mark it's progress, plus error handling
GameVar@ questVar = GetLocalVar(LVAR_q_turo_prog, player.Id);
if(valid(questVar))
{
// is quest still in progress and before repairing the robot
if (questVar < 30)
{
// Check if repair skill is used on the robot
if(skill == SK_REPAIR)
{
player.Say(SAY_NETMSG, "You don't think it can be done without some small energy cells.");
return true;
}
// Check if science skill is used on the robot
if(skill == SK_SCIENCE)
{
player.Say(SAY_NETMSG, "The robot is running very low on energy.");
return true;
}
// Check if the player used a Small Energy Cell on the robot.
if(valid(item))
{
if(item.GetProtoId() == PID_SMALL_ENERGY_CELL)
{
player.Say(SAY_NETMSG, "You replace one of the energy cells of the robot.");
// Set the quest progress
questVar = 30;
// Remove the Small Energy Cells used.
item.SetCount(item.GetCount() - 1);
item.Update();
return true;
}
}
}
else
{
if(skill == SK_REPAIR || skill == SK_SCIENCE)
{
player.Say(SAY_NETMSG, "You already replaced the energy source of this robot, there is nothing more you can do here.");
return true;
}
}
}
return false;
}
#include "utils_h.fos"
#include "worldmap_h.fos"
#include "npc_planes_h.fos"
#include "entire.fos"
#include "_colors.fos"
// function called as request from dialog to spawn quest location
void r_SpawnLoc(Critter& player, Critter@ npc)
{
// roll X,Y value of WM (World Map) zone index, in this case from 3x2 zones area near Hub
uint zoneX = Random(28, 31);
uint zoneY = Random(39, 40);
// get X,Y value of quest location position on WM in zone we picked above
uint wx = zoneX * __GlobalMapZoneLength; //get zone X,Y start value
uint wy = zoneY * __GlobalMapZoneLength;
wx += Random(0, __GlobalMapZoneLength); //add random value from 0 to zone size
wy += Random(0, __GlobalMapZoneLength);
// you can add more map locations here, and select one randomly
array<uint16> locationIds = { 91 };
uint num = locationIds.length;
// pick random encounter map, if only one map, then only one will be selected
uint16 locPid = locationIds[Random(0, num - 1)];
// create quest location
Critter@[] crits = { player };
int loc = CreateLocation(locPid, wx, wy, crits);
if(loc == 0)
return;
// makes the location visible to the player
player.SetKnownLoc(true, loc);
// change location color on World Map
Location@ location = GetLocation(loc);
location.Color = COLOR_RED;
location.Update();
// set TB combat mode if needed
if(player.Mode[MODE_DEFAULT_COMBAT] == COMBAT_MODE_TURN_BASED)
{
SetTurnBasedAvailability(location);
}
// set location id to quest lvar (used when you need to delete location)
GameVar@ locidv = GetLocalVar(LVAR_q_gen_locid, player.Id);
locidv = loc;
// player can die and come back, but we will have to delete the location later
location.AutoGarbage = false;
}
// dialog function used in request to delete quest location (after player report finishing the quest)
void r_DeleteLoc(Critter& player, Critter@ npc)
{
GameVar@ var = GetLocalVar(LVAR_q_gen_locid, player.Id);
DeleteLocation(var.GetValue());
}
/**< Credits and description */
//
// FOnline: 2238
// Rotators
//
// quest_la_dogs.fos
//
/**< These are includes. They tell the compiler where to look after code not defined in this file. */
#include "quest_killmobs_h.fos"
#include "worldmap_h.fos"
#include "utils_h.fos"
#include "npc_planes_h.fos"
#include "entire.fos"
/**< Same as include, I don't know why this is separated from the other includes. This line includes only one function, not all of them. */
import uint GetZonesWithFlag(uint flag, array<IZone@>@ zones) from "worldmap";
/**< Definitions to help to understand and use the code easier. */
#define ALL_KILLED (2)
#define IDLE_NORMAL (3000)
#define DIALOG (9471)
#define PID (82)
// the time after dog group is added to the zone it's been removed from
#define GROUP_RESPAWN_TIME (REAL_HOUR(Random(20, 30)))
// check if there is some group of dog roaming on the worldmap near LA
/**< Checks the map for roaming dogs. It's use has be shortcut to always return true, that is probably to optimize?. Useless currently.*/
bool d_CheckDogs(Critter& player, Critter@ npc)
{
return true;
/*IZone@[] zones;
uint num = GetZonesWithFlag(FLAG_LA_Surroundings, zones);
for(uint i = 0; i < num; i++)
if(zones[i].GetBaseQuantity(GROUP_Dog) > 0) return true;
return false;*/
}
/**< Opposite of checkdogs, always returns false. Useless currently. */
bool d_NoDogs(Critter& player, Critter@ npc)
{
return !d_CheckDogs(player, npc);
}
/**< Spawns the location, sets up the critters, events, timers, initializes everything */
void r_SpawnLoc(Critter& player, Critter@ npc)
{
/**< Get collection of zones near LA Boneyard. */
array<IZone@> zones;
uint num = GetZonesWithFlag(FLAG_LA_Surroundings, zones);
array<IZone@> dogzones;
/**< Cycle through the zones around LA Boneyard and add the zones that contain dogs to another collection called dogzones */
for(uint i = 0; i < num; i++)
if(zones[i].GetBaseQuantity(GROUP_Dog) > 0)
dogzones.insertLast(zones[i]);
/**< If no zones with dogs in it found, exit without spawning location.*/
if(dogzones.length() == 0)
return;
/**< Get a random zone from the dogzones. */
IZone@ zone = random_from_array(dogzones);
/**< Generate random World Map coordinates. */
uint wx = zone.GetX() * __GlobalMapZoneLength;
uint wy = zone.GetY() * __GlobalMapZoneLength;
wx += Random(0, __GlobalMapZoneLength);
wy += Random(0, __GlobalMapZoneLength);
/**< Select a random location on the World Map zone. (square)*/
array<uint16> pids;
num = zone.GetLocationPids(pids);
uint16 locPid = pids[Random(0, num - 1)];
/**< Create the location, add the player */
Critter@[] crits = { player };
int loc = CreateLocation(locPid, wx, wy, crits);
if(loc == 0)
return;
/**< Make the location visible for the player */
player.SetKnownLoc(true, loc);
/**< Get the game variable q_la_dogs_locid and store the location id associated with the players quest. */
GameVar@ locidv = GetLocalVar(LVAR_q_la_dogs_locid, player.Id);
/**< GameVar is a handle to the _la_dogs_locid game variable, it's value will be stored there when this function terminates. */
locidv = loc;
/**< Get the location, allow turn based mode in it, and disable auto garbage, this way the player can revisit the map. */
Location@ location = GetLocation(loc);
if(player.Mode[MODE_DEFAULT_COMBAT] == COMBAT_MODE_TURN_BASED)
SetTurnBasedAvailability(location);
location.AutoGarbage = false;
/**< Get the maps of the location and initialize them with default values. */
array<Map@> maps;
uint mapcount = location.GetMaps(maps);
for(uint c = 0; c < mapcount; c++)
{
maps[c].SetScript(null);
maps[c].SetEvent(MAP_EVENT_IN_CRITTER, null);
maps[c].SetEvent(MAP_EVENT_CRITTER_DEAD, null);
}
/**< Set the player to be the owner of the first map of the location. */
Map@ map = GetLocation(loc).GetMapByIndex(0);
SetOwnerId(map, player.Id);
/**< Repeat until dogs are spawned successfully on the map. */
// spawn dogz
bool spawned = false;
while(!spawned)
{
array<Entire> entires;
ParseEntires(map, entires, 0);
/**< Get a random Entire to spawn the player to, when he enters the map. */
Entire@ ent = random_from_array(entires);
/**< Get a hex position at a random angle and distance from the player to spawn the dogs to. */
uint16 hx = ent.HexX;
uint16 hy = ent.HexY;
map.GetHexCoord(ent.HexX, ent.HexY, hx, hy, Random(0, 359), Random(10, 40));
for(uint i = 0, j = Random(7, 12); i < j; i++)
{
int[] params =
{
ST_DIALOG_ID, DIALOG
};
/**< Creates a dog and adds it to the map. Assignes critter_init function to dogs, explained below, at definition.*/
Critter@ doggie = map.AddNpc(PID, hx, hy, Random(0, 5), params, null, "quest_la_dogs@critter_init");
/**< If creating and adding at least one dog to the map succeded, then the main cycle stops. */
if(valid(doggie))
{
spawned = true;
}
}
}
/**< Makes sure the location is salvaged after 12 hours, if the player does not finish quest until then.
It will also set q_la_dogs variable to 3 (need to check dialog tree, probably reseting quest) */
SetQuestGarbager(12 * 60, player.Id, loc, LVAR_q_la_dogs, 3);
}
/**< Deletes the location the player killed the dogs at. */
void r_DeleteLoc(Critter& player, Critter@ npc)
{
GameVar@ var = GetLocalVar(LVAR_q_la_dogs_locid, player.Id);
DeleteLocation(var.GetValue());
}
/**< Critters need an initialization function to be functional, well, this is it. */
void critter_init(Critter& cr, bool firstTime)
{
/**< Disables replication for killed dogs. */
cr.StatBase[ST_REPLICATION_TIME] = REPLICATION_DELETE;
/**< A bunch of event handler: each will set the function to be called when the event happens. */
cr.SetEvent(CRITTER_EVENT_DEAD, "_DogDead");
cr.SetEvent(CRITTER_EVENT_ATTACKED, "_DogAttacked");
cr.SetEvent(CRITTER_EVENT_MESSAGE, "_DogOnMessage");
cr.SetEvent(CRITTER_EVENT_IDLE, "_DogIdle");
cr.SetEvent(CRITTER_EVENT_SHOW_CRITTER, "_DogShowCritter");
/**< I don't understand what this does, if someone finds out, please tell me as well. */
_CritSetExtMode(cr, MODE_EXT_MOB);
}
/**< Function to run when mob is idle. It move from time to time, but only a few hexes.*/
void _DogIdle(Critter& mob)
{
MobIdle(mob);
}
/**< This is called when a new critter is in sight of the dog. */
void _DogShowCritter(Critter& mob, Critter& showCrit)
{
/**< If the seen creature is not the same type, it will attack it. */
MobShowCritter(mob, showCrit);
}
/**< Checks if all dogs are dead on the map. */
void _DogDead(Critter& cr, Critter@ killer)
{
uint16[] pids = { cr.GetProtoId() };
Map@ map = cr.GetMap();
if(MobsDead(map, pids))
{
GameVar@ var = GetLocalVar(LVAR_q_la_dogs, GetOwnerId(map));
var = ALL_KILLED;
/**< These parts have been severed by someone, it seems that some useless code remained. */
// remove one dog group from given zone
IZone@ zone = GetZone(cr.WorldX, cr.WorldY);
// zone.ChangeQuantity(GROUP_Dog, -1);
// spawn event to restore the doggie
uint[] values = { cr.WorldX, cr.WorldY };
CreateTimeEvent(AFTER(GROUP_RESPAWN_TIME), "e_SpawnDogGroup", values, true);
}
}
/**< Useless code, it was used for extra reality, but someone changed the core part. */
uint e_SpawnDogGroup(array<uint>@ values)
{
IZone@ zone = GetZone(values[0], values[1]);
// zone.ChangeQuantity(GROUP_Dog, 1);
return 0;
}
/**< How dog handles when it is attacked. It will send a message on the map to everyone that he is attacked including itself. (Yeah, I know, lol) */
bool _DogAttacked(Critter& cr, Critter& attacker)
{
return MobAttacked(cr, attacker);
}
/**< If the message is that a dog is attacked, it will attack the attacker. */
void _DogOnMessage(Critter& cr, Critter& fromCr, int message, int value)
{
MobOnMessage(cr, fromCr, message, value);
}
Make sure you don't alt+tab when the console is opened. It's bugged. You won't be able to close the console if you do... Will have to relaunch the mapper. Oh and you'll lose the progress with no way to save it :)
- Launch Mapper and load the map of The Hub
- Press enter after mapper started to get the console.
- Type: "~hub" - to load the map.
- Press F8 to disable mouse scrolling. (This can be very annoying, since even if the Mapper does not have focus, it will try to scroll while you are working with other apps.
- Press Enter again, when the command line is empty, so the command line disappears, now you can use the arrow keys to scroll around.
Save the map: "^tut_map1"
To load a saved map, type "~<map name>" in the console.
TO save a map, type "^<map name> [/text] [/nopack]". "/text" to save it in text format, "/nopack" to save it in unpacked version.
Other commands, preceded with "*":
new create a new map;
unload unload the current map;
scripts list of scripts;
size <w> <h> set a new map size;
dupl search for items with the same pids, placed on the same hexes;
scroll search for scroll blockes, around which there are less than two other scroll blockers;
pidpos <pid> search for all items with a given pid;
hex <hx> <hy> search for all objects on a given hex.
To run a script function, use "#". Executed function must be of prototype "string FuncName(string)", string argument is passed from a console, and function results will be displayed in the message box. Default module is "main", to execute a function from another module use "@" (for example, "#module@MyFunc").
Example:
In console, "#MyFunc Hello wo";
In script, "string MyFunc(string my) { return my + "rld!"; }";
Result in the message box: "Result: Hello world!".
Scripts are placed in the "/data" directory. List of loaded scripts is in scripts.cfg. The main script is mapper_main.fos, which contains all reserved functions, and basic list of API functions.
The mapper does not support FO and FO2 map formats, as well as older FOnline map formats.
On the main panel, there is a range of buttons that group the objects by their type.
Below these buttons, there's a panel with buttons toggling the display of items in the map view.
On the right, there are buttons that determine which objects will be selected by clicking and dragging the mouse.
Other buttons:
Fast - displays list of often used items;
Ign - Ignore, shows ignored objects that are not rendered on the map;
Inv - Inventory, shows objects inside a container or inside critters' inventory;
Lst - List, shows all loaded maps and allows to switch between them.
Upon selecting an object, an option window will appear allowing to edit some of it's properties (marked green; white are not editable).
To add an object to Ignored objects list, click it with Ctrl on the object selection panel.
To add an object to the container or inventory, click it with Alt on the object selection panel.
To put an object in a critter's slot, click the item in it's inventory with Shift.
To apply a change in the object properties window to a range of selected objects (of the same type), click To All button.
To remove selected object(s), press Del.
To change direction of a critter, use middle mouse button.
To add a range of objects to already selected objects, hold Ctrl.
To change zoom, use mouse wheel.
To speed up scrolling of objects in the panel, use the following:
Shift - one page,
Ctrl - 100 elements,
Alt - 1000 elements.
To play animation of a selected critter, use "@" command with codes of desired animations. For instance, to play animations of movement, and then using, type "@abal" (case is ignored, as well as whitespaces). If no critter is selected, all critters on the map will play the animation. For information on animation codes, see http://modguide.nma-fallout.com/#Graphics011
To move a critter, hold down Shift and click the desired position.
Hotkeys:
F1: Enable/Disable display of items.
F2: Enable/Disable display of sceneries.
F3: Enable/Disable display of walls.
F4: Enable/Disable display of critter.
F5: Enable/Disable display of tiles.
F6: Enable/Disable display of frequently used objects.
F7: Hide/Show the main panel.
Shift + F7: Fix the position of the main panel (enabled by default).
F8: Enable/Disable scrolling with mouse.
F9: Hide/Show the object properties window.
Shift + F9: Fix the position of the object properties window (disabled by default).
F11: Set rain.
Shift + Escape: Exit the mapper.
Del: Delete the selected objects.
Ctrl + X: Cut objects.
Ctrl + C: Copy objects.
Ctrl + V: Paste objects.
Ctrl + A: Select all.
Ctrl + S: Enable/Disable ignoring of scroll blockers.
Ctrl + B: Show impassable hexes. Red are impassable, and not shootable through. Green are impassable, shootable through.
Ctrl + M: Display NPC information over their heads (this has few modes of display).
Ctrl + L: Save the log to a txt file.
Tab: Change the type of objects selection (diamond or rectangle).
+: Change time by 1 hour.
-: Change time by -1 hour.
Special Entires:
0 - default;
240 - starting position for a player who logged for a first time;
241 - starting position for players on a map with NoLogOff flag.
242 - replication.
243 - car entry point.
245 - vertibird entry point.
246 - boat entry point.
2. Why do we have all these empty fallout2 maps in the maps folder?
9. How do I copy the answers in the dialogue editor? Or how do I use answers for dialogue A from a dialogue B... Looks like I'm missing something here. I could add a technical answer to A that would send the branch to dialogue B, but it's not very elegant
10. I have some more in-depth questions regarding server mechanics, but I'll ask them on fodev.
Now we need an ultimate manual that would unite all the existing manuals. I have read five different manuals on mapping and each has brought something unique. And mapping is not the complex thing. This manual though is the best to start with.
the software fails to add vars. Could you please describe the significance of the flag property.
- $ 3 1 q_turo 0 0 1000 0
- **********
- TuRo progress.
- **********
the software fails to add vars. Could you please describe the significance of the flag property.
- $ 3 1 q_turo 0 0 1000 0
- **********
- TuRo progress.
- **********
I mean, I saw the headers, but they are unclear:
Id Type Name Start Min Max Flags
**************************************************************************************
$ 1 0 car_id 0 0 0 4
What values of Flags mean what? I need a local map variable for an SE. Need it to die when a person leaves the map.
And the checkboxes. What's the meaning of them?
And what's the significance of having variables in the NPC or player? Do I understand it correctly that variables on an NPC can be accessed by other players while variable on a player can be accessed by other NPCs.
Therefore, if my "quest" is very local and affects only 1 npc and one player, it doesn't matter whether I choose NPC or player, I just have to be consistent. Am I understanding it correctly?
Would be nice to update that part of the manual.
And what is recheck?
And I need to do a hack. I've seen this logics somewhere: You talk to an npc, do something and then the same npc answers you with strings.
So what I intuitively did is:
(http://i.imgur.com/raZpCnw.jpg)
if the var is 0, the player never interacted with the npc.
1 - interacted once, but never got to the end.
2 - went to the end and now has to get strings.
And here's what I get
(http://i.imgur.com/7EcKmGm.jpg)
How do I get the strings?
Thanks!
[52:890] ProtoMap::BindSceneryScript - Map<pid<131>, name<se_oasis_cave_cth>>, Can't bind scenery function<s_Disassemble> in module<se_oasis.fos>. Scenery hexX<209>, hexY<101>
// Includes some definitions
#include "_macros.fos"
#include "_dialogs.fos"
#include "_maps.fos"
#include "elevators_h.fos"
#include "factions_h.fos"
#include "mapdata_h.fos"
#include "messages_h.fos"
// Function signature for player interactions with Scenery objects
bool s_Disassemble(Critter& player, Scenery& robot)
{
return RunDialog(player,robot.HexX, robot.HexY, 31338,false);
}
F:\Games\Fonline\Mapping\Server\scripts>ascompiler.exe se_oasis.fos -p prep.txt -d __SERVERs
Compiling se_oasis.fos ...
Success.
Time: 82,0483 ms.
F:\Games\Fonline\Mapping\Server\scripts>