Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2005:
[Freeciv-Dev] Re: (PR#7245) Wish List: Freeciv Tutorial
Home

[Freeciv-Dev] Re: (PR#7245) Wish List: Freeciv Tutorial

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: gang65@xxxxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#7245) Wish List: Freeciv Tutorial
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 11 May 2005 01:00:33 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=7245 >

Here's another update to the tutorial.

Added signals:
  building_built (building, city)
  unit_cant_be_built (unittype, city, reason)
  building_cant_be_built (building, city, reason)
  tech_researched (tech, player, source)

The "reason" and "source" arguments are simple string identifiers to
tell why the item couldn't be built, or where the newly acquired tech
came from.

In addition I fixed the hut_enter signal so it wouldn't pass in a killed
unit.

In addition to the above, the changes to the tutorial itself are extensive.

-jason


Index: data/scenario/tutorial.sav
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/scenario/tutorial.sav,v
retrieving revision 1.2
diff -u -r1.2 tutorial.sav
--- data/scenario/tutorial.sav  10 May 2005 13:24:02 -0000      1.2
+++ data/scenario/tutorial.sav  11 May 2005 07:59:24 -0000
@@ -7,7 +7,7 @@
 task is to conquer the world!  You should start by\\n\
 exploring the land around you with your explorer,\\n\
 and using your settlers to find a good place to build\\n\
-a city.'))
+a city.  Use the number pad to move units around.'))
   end
 end
 signal.connect('turn_started', 'turn_callback')
@@ -42,14 +42,14 @@
 You probably want to build some settlers first, so as to expand your\\n\
 civilization further.  Click on the production tab, then click on the\\n\
 settler unit from the list of possible productions, then click on the\\n\
-Change button to begin building it before closing the city dialog.  If\\n\
-all goes well the city should display the settler production on the\\n\
-map view.'))
+Change button to begin building it.  When you are done, close the city\\n\
+dialog.  If all goes well the city should display the settler\\n\
+production on the map view.'))
     elseif citiesbuilt == 1 then
       notify.event(city:owner(), city.tile, E.TUTORIAL,
 _('Congratulations, you have founded your second city.  This city will\\n\
 behave almost exactly like the first one - it will be slightly different\\n\
-because of the terrain it is built around.  You probably want to build\\n\
+because of the terrain around it.  You probably want to build\\n\
 settlers here too.'))
     elseif citiesbuilt == 2 then
       notify.event(city:owner(), city.tile, E.TUTORIAL,
@@ -66,6 +66,29 @@
 to begin building them.  Then double-click on a military unit to\\n\
 append it to the worklist.  As soon as the Barracks are complete the\\n\
 city will automatically switch over to producing the unit.'))
+    elseif citiesbuilt == 3 then
+      notify.event(city:owner(), city.tile, E.TUTORIAL,
+_('Another city!  You are really getting the hang of this.  You\\n\
+probably have a pretty good idea what to do with new cities by\\n\
+now.  Take a moment to look at the bar below the city on the map\\n\
+view.  This display shows some useful information about the city.\\n\
+The flag and background color indicate what civilization the city\\n\
+belongs to (this will be useful when you meet other civilizations).\\n\
+The top row of the bar also shows the name and size of the city, and\\n\
+will show one or more starts to indicate if there are units in the\\n\
+city.  The bottom row shows what the city is building, and how long it\\n\
+will take; it also shows how long the city will take to grow to the\\n\
+next largest size.'))
+    elseif citiesbuilt == 4 then
+      notify.event(city:owner(), city.tile, E.TUTORIAL,
+_('As the number of cities in your empire grows, it becomes harder to\\n\
+manage individual cities.  This is where the city report becomes\\n\
+useful.  Press F1 to bring it up.  This report shows a list of cities\\n\
+with various statistics about each.  Play around with it a bit if you\\n\
+like (return to the map view by clicking on the Map tab).  With a bit\\n\
+of practice it is possible to control almost every aspect of the cities\\n\
+from this report.  The full power of the city report is beyond the\\n\
+scope of this tutorial, however.'))
     end
     citiesbuilt = citiesbuilt + 1
   end
@@ -85,12 +108,12 @@
 If your city is building settlers, you should consider buying them\\n\
 now.  Open the city dialog and click on the Buy button.  This trades\\n\
 in gold (if you have enough of it) to instantly complete the\\n\
- production.'))
+production.'))
       growth2msg = true
     elseif size == 3 and not growth3msg then
       notify.event(city:owner(), city.tile, E.TUTORIAL,
 _('Your city has grown again!  Now with three citizens you have\\n\
-a fair amount of choice over where the city should focuse its\\n\
+a fair amount of choice over where the city should focus its\\n\
 resources.  A city with three citizens gets to work three\\n\
 different tiles, in addition to its center tile which is worked\\n\
 for free.  In the city dialog, the map shows which tiles are working\\n\
@@ -164,11 +187,16 @@
 signal.connect('city_growth', 'city_growth_callback')
 
 function unit_built_callback(unit)
-  if not settlermsg and unit:type().name == 'Settlers' then
-    notify.event(unit:owner(), unit.tile, E.TUTORIAL,
+  if not unit:owner():is_human() then
+    return
+  end
+  if unit:type().name == 'Settlers' then
+    if settlersbuilt == 0 then
+      notify.event(unit:owner(), unit.tile, E.TUTORIAL,
 _('You have built a settler unit.  Settlers are best used to build \\n\
 new cities, so as to expand your civilization.  Move your settler\\n\
-away from your existing cities to find a spot for a new city.\\n\
+away from your existing cities to find a spot for a new city.  When\\n\
+you have picked a spot press B to build the city.\\n\
 \\n\
 Again, cities are best built on open ground near water.  Grassland\\n\
 and plains provide food for the city.  Forests and hills provide\\n\
@@ -177,12 +205,166 @@
 tundra, and mountains generally provide little output and are not\\n\
 of much use to small cities.  See the help on terrain and specials\\n\
 for more information about terrain specs.'))
-    settlermsg = true
+    elseif settlersbuilt == 1 then
+      notify.event(unit:owner(), unit.tile, E.TUTORIAL,
+_('Your second Settlers should also be used to build a new city.\\n\
+Notice how when you move the Settlers away from your existing cities\\n\
+an outline is drawn around them.  This shows the area that would be\\n\
+covered by a city built at this location; it fits in with the outline\\n\
+already on the map view that shows which tiles are covered by your\\n\
+existing cities.  Generally when building new cities you want to make\\n\
+sure that all tiles are covered by at least one city, but after that\\n\
+it is best that your cities overlap as little as possible.  Spreading\\n\
+out cities properly gives each city access to more resrouces, allowing\\n\
+them to grow to larger sizes.'))
+    end
+    settlersbuilt = settlersbuilt + 1
   end
 end
-settlermsg = false
+settlersbuilt = 0
 signal.connect('unit_built', 'unit_built_callback')
 
+function building_built_callback(building, city)
+  if not city:owner():is_human() then
+    return
+  end
+  if building.name == 'Barracks' and not barracksmsg then
+    notify.event(city:owner(), city.tile, E.TUTORIAL,
+_('You have built a Barracks.  This building will make any military\\n\
+units you build start out as veterans.  Veteran units are stronger\\n\
+than inexperienced (green) troops, and will survive longer in\\n\
+combat.  See the help on buildings for more information about this\\n\
+and other buildings.\\n\
+\\n\
+You probably want to start building a military unit in the city\\n\
+that built the Barracks.  A barracks are a significant investment\\n\
+and have a small upkeep as well, so it is not a good idea to let\\n\
+them go to waste.'))
+    barracksmsg = true
+  end
+end
+barracksmsg = false
+signal.connect('building_built', 'building_built_callback')
+
+function unit_cant_be_built_callback(unittype, city, reason)
+  if not city:owner():is_human() then
+    return
+  end
+  if unittype.name == 'Settlers' and not nosettlermsg then
+    notify.event(city:owner(), city.tile, E.TUTORIAL,
+_('Your city cannot build a settler.  Settlers take one unit of\\n\
+population to build, so a city of size one cannot build one without\\n\
+disbanding the city.\\n\
+\\n\
+To remedy this, you need to adjust the citizens in the city to\\n\
+provide more food so as to grow the city faster.  Cities that\\n\
+do not have much food should not try to build settlers.  When\\n\
+founding a new city, make sure it is built on terrain that provides\\n\
+enough food - grassland is best; plains or hills are almost as good.'))
+    nosettlermsg = true
+  elseif not unittype:has_flag('NonMil') and not nomilmsg then
+notify.event(city:owner(), city.tile, E.TUTORIAL,
+_('You have built your first military unit!  Military units have two\\n\
+basic purposes: attack and defense.  Each unit has an attack strength\\n\
+and a defense strength.  While a Warriors is a measly 1/1, a Phalanx\\n\
+is a must stronger defender with 2 defense (1/2).  A Catapult is a good\\n\
+attacking unit because it has 6 attack (6/1).\\n\
+\\n\
+Usually it is a good idea to keep one or two defenders in each city.\\n\
+Important cities like your capital may deserve extra protection.  Units\\n\
+built in one city may be sent to another city to defend (press the G\\n\
+key to enter goto mode to move units easily over distances).  If you\\n\
+are at war, however, you may wish to move your unit toward an enemy\\n\
+city to attack.  Be careful not to lose it though!'))
+    nomilmsg = true
+  end
+end
+nosettlermsg = false
+nomilmsg = false
+signal.connect('unit_cant_be_built', 'unit_cant_be_built_callback')
+
+function tech_researched_callback(tech, player, reason)
+  if not player:is_human() or not (reason == 'researched') then
+    return
+  end
+  if numtechs == 0 then
+    notify.event(player, nil, E.TUTORIAL,
+_('You have researched your first technology!  Technological advances\\n\
+are an integral concept in Freeciv.  As you increase your technology\\n\
+level new units, buildings, governments, and various free bonuses will\\n\
+become available to you.\\n\
+\\n\
+For now, go over into the Science Dialog and play around a little.\\n\
+Press F6 to open the science dialog (or click on the Science tab in\\n\
+the main window area).  Find the technology called Republic and click\\n\
+on it.  Now Republic has been set as your technology goal; this means\\n\
+the next advance on the path toward this technology will automatically\\n\
+be chosen to research.  In the top of the window it shows how much\\n\
+scientific research you are accomplishing each turn - research (bulbs)\\n\
+comes from the taxable trade in your cities.  In the bottom of the\\n\
+window is the tech tree; here you may left-click to set the research\\n\
+target or research goal, or right-click to get help about a particular\\n\
+technology.  When you are done playing around click on the Map tab\\n\
+(Alt-M) to return to the map view.'))
+  elseif numtechs == 1 then
+    notify.event(player, nil, E.TUTORIAL,
+_('Now you have researched your second technology.  Go back into the\\n\
+science dialog (F6) and take a quick look at your progress.  If you\\n\
+set Republic as your technology goal earlier, a new research target\\n\
+should have been chosen for you automatically.  If you do not have\\n\
+any goal set, however, there will not be any new target chosen until\\n\
+the end of the turn.\\n\
+\\n\
+In the turn when you complete your research, you can pick a new tech\\n\
+to research.  However, switching targets midway through researching a\\n\
+particular technology costs you all of the research done on\\n\
+it so far.  Setting your technology goal wisely means you do not have\\n\
+to worry about picking a new research target each time you finish\\n\
+researching a technology.'))
+  elseif tech.name == 'Republic' then
+    notify.event(player, nil, E.TUTORIAL,
+_('You have successfully completed research into The Republic.  This\\n\
+technology is particularly useful because it allows a new form of\\n\
+government.  The government your civilization follows is very\\n\
+important in determining your development.  In the beginning you\\n\
+started as a Despotism, a very inefficient form of government.  Later\\n\
+government options will give you some choice of whether your\\n\
+civilization is to be a peaceful trading nation or a conquering\\n\
+juggernaut.  Each has advantages.\\n\
+\\n\
+For now, you probably want to switch staight into Republic.  In the\\n\
+Government menu, go to the Change Government submenu and choose\\n\
+Republic.  Yes you want a revolution!  Changing governments means\\n\
+going through a few turns of anarchy, so it is not without cost.\\n\
+However Republic is a substantially better form of government\\n\
+than Despotism so the investment will soon pay off.'))
+  end
+  numtechs = numtechs + 1
+end
+numtechs = 0
+signal.connect('tech_researched', 'tech_researched_callback')
+
+function hut_entered_callback(unit)
+  if not unit:owner():is_human() then
+    return
+  end
+  if not hutmsg then
+    notify.event(unit:owner(), unit.tile, E.TUTORIAL,
+_('Your unit has found a Hut.  These are small villages scattered across\\n\
+the landscape.  When a unit enters one several things may happen.  The\\n\
+most likely outcome is that you will find resources worth a small\\n\
+amount of gold.  However it is also possible to find technologies or\\n\
+mercenary units inside a hut.  Some huts contain native settlers\\n\
+that will join your civilization and bring a new city into your\\n\
+empire.  Finally, some huts contain barbarians which will kill your\\n\
+unit instantly.  On average, it is beneficial to search out and enter\\n\
+any huts you find as soon as possible.'))
+    hutmsg = true
+  end
+end
+hutmsg = false
+signal.connect('hut_enter', 'hut_entered_callback')
+
 print 'Loading tutorial events.'
 "
 
@@ -292,7 +474,7 @@
 wetness=50
 steepness=30
 huts=50
-generator=3
+generator=1
 have_huts=0
 temperature=50
 alltemperate=0
Index: server/cityturn.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/cityturn.c,v
retrieving revision 1.315
diff -u -r1.315 cityturn.c
--- server/cityturn.c   10 May 2005 19:08:56 -0000      1.315
+++ server/cityturn.c   11 May 2005 07:59:25 -0000
@@ -625,7 +625,8 @@
     /* Sanity checks */
     if (is_unit &&
        !can_build_unit(pcity, target)) {
-      int new_target = unit_upgrades_to(pcity, target);
+      struct unit_type *ptarget = get_unit_type(target);
+      Unit_type_id new_target = unit_upgrades_to(pcity, target);
 
       /* Maybe we can just upgrade the target to what the city /can/ build. */
       if (new_target == U_NOT_OBSOLETED) {
@@ -635,6 +636,10 @@
                           "tech not yet available.  Postponing..."),
                         pcity->name,
                         get_unit_type(target)->name);
+       script_signal_emit("unit_cant_be_built", 3,
+                          API_TYPE_UNIT_TYPE, ptarget,
+                          API_TYPE_CITY, pcity,
+                          API_TYPE_STRING, "need_tech");
        continue;
       } else if (!can_eventually_build_unit(pcity, new_target)) {
        /* If the city can never build this unit or its descendants,
@@ -647,6 +652,10 @@
                            in the worklist, not its obsolete-closure
                            new_target. */
                         get_unit_type(target)->name);
+       script_signal_emit("unit_cant_be_built", 3,
+                          API_TYPE_UNIT_TYPE, ptarget,
+                          API_TYPE_CITY, pcity,
+                          API_TYPE_STRING, "never");
        /* Purge this worklist item. */
        worklist_remove(&pcity->worklist, i-1);
        /* Reset i to index to the now-next element. */
@@ -664,15 +673,21 @@
       }
     } else if (!is_unit && !can_build_improvement(pcity, target)) {
       Impr_type_id new_target = building_upgrades_to(pcity, target);
+      struct impr_type *ptarget = get_improvement_type(target);
 
       /* If the city can never build this improvement, drop it. */
       if (!can_eventually_build_improvement(pcity, new_target)) {
+
        /* Nope, never in a million years. */
        notify_player_ex(pplayer, pcity->tile, E_CITY_CANTBUILD,
                         _("%s can't build %s from the worklist.  "
                           "Purging..."),
                         pcity->name,
                         get_impr_name_ex(pcity, target));
+       script_signal_emit("building_cant_be_built", 3,
+                          API_TYPE_BUILDING_TYPE, ptarget,
+                          API_TYPE_CITY, pcity,
+                          API_TYPE_STRING, "never");
 
        /* Purge this worklist item. */
        worklist_remove(&pcity->worklist, i-1);
@@ -709,6 +724,10 @@
                               get_impr_name_ex(pcity, target),
                               get_tech_name(pplayer,
                                             req->source.value.tech));
+             script_signal_emit("building_cant_be_built", 3,
+                                API_TYPE_BUILDING_TYPE, building,
+                                API_TYPE_CITY, pcity,
+                                API_TYPE_STRING, "need_tech");
              break;
            case REQ_BUILDING:
              notify_player_ex(pplayer, pcity->tile, E_CITY_CANTBUILD,
@@ -718,6 +737,10 @@
                               get_impr_name_ex(pcity, target),
                               get_impr_name_ex(pcity,
                                                req->source.value.building));
+             script_signal_emit("building_cant_be_built", 3,
+                                API_TYPE_BUILDING_TYPE, building,
+                                API_TYPE_CITY, pcity,
+                                API_TYPE_STRING, "need_building");
              break;
            case REQ_GOV:
              notify_player_ex(pplayer, pcity->tile, E_CITY_CANTBUILD,
@@ -726,6 +749,10 @@
                               pcity->name,
                               get_impr_name_ex(pcity, target),
                               get_government_name(req->source.value.gov));
+             script_signal_emit("building_cant_be_built", 3,
+                                API_TYPE_BUILDING_TYPE, building,
+                                API_TYPE_CITY, pcity,
+                                API_TYPE_STRING, "need_government");
              break;
            case REQ_SPECIAL:
              notify_player_ex(pplayer, pcity->tile, E_CITY_CANTBUILD,
@@ -734,6 +761,10 @@
                               pcity->name,
                               get_impr_name_ex(pcity, target),
                               get_special_name(req->source.value.special));
+             script_signal_emit("building_cant_be_built", 3,
+                                API_TYPE_BUILDING_TYPE, building,
+                                API_TYPE_CITY, pcity,
+                                API_TYPE_STRING, "need_special");
              break;
            case REQ_TERRAIN:
              notify_player_ex(pplayer, pcity->tile, E_CITY_CANTBUILD,
@@ -742,6 +773,10 @@
                               pcity->name,
                               get_impr_name_ex(pcity, target),
                               get_terrain_name(req->source.value.terrain));
+             script_signal_emit("building_cant_be_built", 3,
+                                API_TYPE_BUILDING_TYPE, building,
+                                API_TYPE_CITY, pcity,
+                                API_TYPE_STRING, "need_terrain");
              break;
            case REQ_NATION:
              /* FIXME: we should skip rather than postpone, since we'll
@@ -752,6 +787,10 @@
                               pcity->name,
                               get_impr_name_ex(pcity, target),
                               get_nation_name(req->source.value.nation));
+             script_signal_emit("building_cant_be_built", 3,
+                                API_TYPE_BUILDING_TYPE, building,
+                                API_TYPE_CITY, pcity,
+                                API_TYPE_STRING, "need_nation");
              break;
            case REQ_UNITTYPE:
            case REQ_UNITFLAG:
@@ -765,6 +804,10 @@
                                 "city must be of size %d.  Postponing..."),
                               pcity->name, get_impr_name_ex(pcity, target),
                               req->source.value.minsize);
+             script_signal_emit("building_cant_be_built", 3,
+                                API_TYPE_BUILDING_TYPE, building,
+                                API_TYPE_CITY, pcity,
+                                API_TYPE_STRING, "need_minsize");
              break;
            case REQ_NONE:
            case REQ_LAST:
@@ -1001,6 +1044,7 @@
   bool space_part;
   int mod;
   Impr_type_id id = pcity->currently_building;
+  struct impr_type *building = get_improvement_type(id);
 
   if (get_current_construction_bonus(pcity, EFT_PROD_TO_GOLD) > 0) {
     assert(pcity->surplus[O_SHIELD] >= 0);
@@ -1017,6 +1061,10 @@
                     _("%s is building %s, which "
                       "is no longer available."),
                     pcity->name, get_impr_name_ex(pcity, id));
+    script_signal_emit("building_cant_be_built", 3,
+                      API_TYPE_BUILDING_TYPE, building,
+                      API_TYPE_CITY, pcity,
+                      API_TYPE_STRING, "unavailable");
     return TRUE;
   }
   if (pcity->shield_stock >= impr_build_shield_cost(id)) {
@@ -1067,6 +1115,9 @@
     notify_player_ex(pplayer, pcity->tile, E_IMP_BUILD,
                     _("%s has finished building %s."), pcity->name,
                     get_improvement_name(id));
+    script_signal_emit("building_built", 2,
+                      API_TYPE_BUILDING_TYPE, get_improvement_type(id),
+                      API_TYPE_CITY, pcity);
 
 
     if ((mod = get_current_construction_bonus(pcity, EFT_GIVE_IMM_TECH))) {
@@ -1122,7 +1173,10 @@
 **************************************************************************/
 static bool city_build_unit(struct player *pplayer, struct city *pcity)
 {
+  struct unit_type *utype;
+
   upgrade_unit_prod(pcity);
+  utype = get_unit_type(pcity->currently_building);
 
   /* We must make a special case for barbarians here, because they are
      so dumb. Really. They don't know the prerequisite techs for units
@@ -1132,6 +1186,10 @@
     notify_player_ex(pplayer, pcity->tile, E_CITY_CANTBUILD,
         _("%s is building %s, which is no longer available."),
         pcity->name, unit_name(pcity->currently_building));
+    script_signal_emit("unit_cant_be_built", 3,
+                      API_TYPE_UNIT_TYPE, utype,
+                      API_TYPE_CITY, pcity,
+                      API_TYPE_STRING, "unavailable");
     freelog(LOG_VERBOSE, _("%s's %s tried build %s, which is not available"),
             pplayer->name, pcity->name, unit_name(pcity->currently_building)); 
           
     return TRUE;
@@ -1151,6 +1209,10 @@
       notify_player_ex(pplayer, pcity->tile, E_CITY_CANTBUILD,
                       _("%s can't build %s yet."),
                       pcity->name, unit_name(pcity->currently_building));
+      script_signal_emit("unit_cant_be_built", 3,
+                        API_TYPE_UNIT_TYPE, utype,
+                        API_TYPE_CITY, pcity,
+                        API_TYPE_STRING, "pop_cost");
       return TRUE;
     }
 
@@ -1482,6 +1544,7 @@
   struct player *pplayer = city_owner(pcity);
   struct tile *ptile = pcity->tile;
   struct city *rcity=NULL;
+  struct unit_type *utype = get_unit_type(pcity->currently_building);
 
   /* find closest city other than pcity */
   rcity = find_closest_owned_city(pplayer, ptile, FALSE, pcity);
@@ -1492,6 +1555,10 @@
                     _("%s can't build %s yet, "
                     "and we can't disband our only city."),
                     pcity->name, unit_name(pcity->currently_building));
+    script_signal_emit("unit_cant_be_built", 3,
+                      API_TYPE_UNIT_TYPE, utype,
+                      API_TYPE_CITY, pcity,
+                      API_TYPE_STRING, "pop_cost");
     return FALSE;
   }
 
Index: server/diplhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/diplhand.c,v
retrieving revision 1.93
diff -u -r1.93 diplhand.c
--- server/diplhand.c   1 May 2005 16:18:14 -0000       1.93
+++ server/diplhand.c   11 May 2005 07:59:25 -0000
@@ -29,6 +29,8 @@
 #include "player.h"
 #include "unit.h"
 
+#include "script.h"
+
 #include "citytools.h"
 #include "cityturn.h"
 #include "gamelog.h"
@@ -358,6 +360,10 @@
                         get_tech_name(pdest, pclause->value),
                         get_nation_name_plural(pgiver->nation));
 
+       script_signal_emit("tech_researched", 3,
+                          API_TYPE_TECH_TYPE, &advances[pclause->value],
+                          API_TYPE_PLAYER, pdest,
+                          API_TYPE_STRING, "traded");
         gamelog(GAMELOG_TECH, pdest, pgiver, pclause->value, "acquire");
         gamelog(GAMELOG_TREATY, GL_TECH, pgiver, pdest);
        do_dipl_cost(pdest);
Index: server/plrhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v
retrieving revision 1.376
diff -u -r1.376 plrhand.c
--- server/plrhand.c    6 May 2005 03:23:55 -0000       1.376
+++ server/plrhand.c    11 May 2005 07:59:25 -0000
@@ -32,6 +32,8 @@
 #include "support.h"
 #include "tech.h"
 
+#include "script.h"
+
 #include "citytools.h"
 #include "cityturn.h"
 #include "connecthand.h"
@@ -157,6 +159,10 @@
        notify_player_ex(pplayer, NULL, E_TECH_GAIN,
                         _("%s acquired from %s!"),
                         get_tech_name(pplayer, i), buf);
+       script_signal_emit("tech_researched", 3,
+                          API_TYPE_TECH_TYPE, &advances[i],
+                          API_TYPE_PLAYER, pplayer,
+                          API_TYPE_STRING, "stolen");
         gamelog(GAMELOG_TECH, pplayer, NULL, i, "steal");
        notify_embassies(pplayer, NULL,
                         _("The %s have acquired %s from %s."),
@@ -500,6 +506,8 @@
 static void tech_researched(struct player* plr)
 {
   /* plr will be notified when new tech is chosen */
+  Tech_type_id tech_id = plr->research->researching;
+  struct advance *tech = &advances[tech_id];
 
   if (!is_future_tech(plr->research->researching)) {
     notify_embassies(plr, NULL,
@@ -514,6 +522,9 @@
                     plr->future_tech);
   
   }
+  script_signal_emit("tech_researched", 3,
+                    API_TYPE_TECH_TYPE, tech, API_TYPE_PLAYER, plr,
+                    API_TYPE_STRING, "researched");
   gamelog(GAMELOG_TECH, plr, NULL, plr->research->researching);
 
   /* Deduct tech cost */
@@ -722,6 +733,10 @@
     } tech_type_iterate_end;
     assert(stolen_tech != A_NONE);
   }
+  script_signal_emit("tech_researched", 3,
+                    API_TYPE_TECH_TYPE, &advances[stolen_tech],
+                    API_TYPE_PLAYER, pplayer,
+                    API_TYPE_STRING, "stolen");
   gamelog(GAMELOG_TECH, pplayer, target, stolen_tech, "steal");
 
   notify_player_ex(pplayer, NULL, E_TECH_GAIN,
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.354
diff -u -r1.354 unittools.c
--- server/unittools.c  10 May 2005 01:03:03 -0000      1.354
+++ server/unittools.c  11 May 2005 07:59:26 -0000
@@ -2297,6 +2297,10 @@
   notify_player_ex(pplayer, punit->tile, E_HUT_TECH,
                   _("You found %s in ancient scrolls of wisdom."),
                   tech_name);
+  script_signal_emit("tech_researched", 3,
+                    API_TYPE_TECH_TYPE, &advances[new_tech],
+                    API_TYPE_PLAYER, pplayer,
+                    API_TYPE_STRING, "hut");
   gamelog(GAMELOG_TECH, pplayer, NULL, new_tech);
   notify_embassies(pplayer, NULL, _("The %s have acquired %s"
                                    " from ancient scrolls of wisdom."),
@@ -2406,6 +2410,8 @@
     hut_chance = 0;
   }
 
+  script_signal_emit("hut_enter", 1, API_TYPE_UNIT, punit);
+
   switch (hut_chance) {
   case 0:
     hut_get_gold(punit, 25);
@@ -2434,8 +2440,6 @@
     break;
   }
 
-  script_signal_emit("hut_enter", 1, API_TYPE_UNIT, punit);
-
   send_player_info(pplayer, pplayer);       /* eg, gold */
   return ok;
 }
Index: server/scripting/script_signal.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/scripting/script_signal.c,v
retrieving revision 1.7
diff -u -r1.7 script_signal.c
--- server/scripting/script_signal.c    10 May 2005 20:33:09 -0000      1.7
+++ server/scripting/script_signal.c    11 May 2005 07:59:26 -0000
@@ -131,6 +131,25 @@
 
   /* Only includes units built in cities, for now. */
   script_signal_create("unit_built", 2, API_TYPE_UNIT, API_TYPE_CITY);
+  script_signal_create("building_built",
+                      2, API_TYPE_BUILDING_TYPE, API_TYPE_CITY);
+
+  /* These can happen for various reasons; the third argument gives the
+   * reason (a simple string identifier).  Example identifiers:
+   * "pop_cost", "need_tech", "need_building", "need_special",
+   * "need_terrain", "need_government", "need_nation", "never",
+   * "unavailable". */
+  script_signal_create("unit_cant_be_built",
+                      3, API_TYPE_UNIT_TYPE, API_TYPE_CITY, API_TYPE_STRING);
+  script_signal_create("building_cant_be_built",
+                      3, API_TYPE_BUILDING_TYPE, API_TYPE_CITY,
+                      API_TYPE_STRING);
+
+  /* The third argument contains the source: "researched", "traded",
+   * "stolen", "hut". */
+  script_signal_create("tech_researched",
+                      3, API_TYPE_TECH_TYPE, API_TYPE_PLAYER,
+                      API_TYPE_STRING);
 
   script_signal_create("hut_enter", 1, API_TYPE_UNIT);
 }

[Prev in Thread] Current Thread [Next in Thread]