Server Help

ASSS Questions - Regions

BDwinsAlt - Wed Sep 27, 2006 6:06 pm
Post subject: Regions
I've never used Regions in ASSS before. I tried working with it, but I didn't have much luck. What I need to do is make a square area where if someone on a certain freq enters it will prize them a warp. Can you help me.

Code: Show/Hide

Example: 25,25,200,200 (square box)


I have found an alternitive. I check the coords in a line so to say, but there has to be an easy way, even though it isn't that hard.
Chambahs - Wed Sep 27, 2006 8:42 pm
Post subject:
Code: Show/Hide

# wpn by Chambahs and Smong
# shark is grunt ship
# apr 11 2005 Chambahs
# apr 13 2005 Smong
# apr 15 2005 smong (bot kill bug fixed)
# jun 19 2005 smong (bigref fix)

from asss import *

chat = get_interface(I_CHAT)
game = get_interface(I_GAME)
mapdata = get_interface(I_MAPDATA)
wpn_bigref = [ None ]
wpn_bigref_count = [ 0 ]

# a list of regions and ships that they are
regions = [ ("minigun", SHIP_WARBIRD), \
            ("flak", SHIP_JAVELIN), \
            ("bio", SHIP_WEASEL), \
            ("rocket", SHIP_LEVIATHAN), \
            ("sniper", SHIP_TERRIER), \
            ("shock", SHIP_SPIDER), \
            ("tank", SHIP_LANCASTER) ]

# the default ship
defaultship = SHIP_SHARK

def make_region_timer(initial, interval):
    def region_timer():
        changeset = []
        # for each player
        def for_each(p):
            # don't bother on non-wpn arenas
            try:
                if not p.arena.wpn_cb1: return
            except: pass

            # sanity checks
            if p.arena and p.status == S_PLAYING and \
                is_human(p) and p.ship < SHIP_SPEC:
                # check regions
                x = p.position[0] / 16
                y = p.position[1] / 16
                for rname, ship in regions:
                    if p.ship != ship:
                        rgn = mapdata.FindRegionByName(p.arena, rname)
                        if rgn != None and mapdata.Contains(rgn, x, y):
                            change = ( p, ship, x, y )
                            changeset.append(change)
                            break
        for_each_player(for_each)

        # change their ship outside for each player loop
        for p, ship, x, y in changeset:
            game.SetShip(p, ship)
            game.WarpTo(p, x, y)
        return 1
    return set_timer(region_timer, initial, interval)

def kill(arena, killer, killed, bty, flags, pts, green):
    if not is_human(killed) or killed.ship >= SHIP_SPEC:
        pass
    elif killed.ship != SHIP_SHARK:
        game.SetShip(killed, SHIP_SHARK)
    return pts, green

# freqman interface (broken?)

def InitialFreq(p, ship, freq):
    ship, freq = p.arena.wpn_oldfm.InitialFreq(p, ship, freq)
    if ship != SHIP_SPEC:
        ship = defaultship
    return ship, freq

def ShipChange(p, ship, freq):
    if ship != SHIP_SPEC:
        ship = defaultship
    return ship, freq   

def FreqChange(p, ship, freq):
    if ship != SHIP_SPEC:
        ship = defaultship
    return ship, freq

myfm = (InitialFreq, ShipChange, FreqChange)

def mm_attach(arena):
    arena.wpn_cb1 = reg_callback(CB_KILL, kill, arena)
    #arena.wpn_oldfm = get_interface(I_FREQMAN, arena)
    #arena.wpn_myfm = reg_interface(I_FREQMAN, myfm, arena)

    # make one timer only
    if wpn_bigref[0] == None:
        wpn_bigref[0] = make_region_timer(500, 100)
    wpn_bigref_count[0] += 1

def mm_detach(arena):
    for attr in ['cb1', 'oldfm', 'myfm']:
        try: delattr(arena, 'wpn_' + attr)
        except: pass

    wpn_bigref_count[0] -= 1
    if wpn_bigref_count[0] <= 0:
        wpn_bigref[0] = None


Code from wpn.py module that deals with regions, you can pretty much see exactly how to handle region coding.
Bak - Thu Sep 28, 2006 12:00 am
Post subject:
Make your regions visually using CLT or DustEd.

Code: Show/Hide

// in mm func
mm->RegCallback(CB_REGION, region_cb, ALLARENAS);
...
mm->UnregCallback(CB_REGION, region_cb, ALLARENAS);

...

// in local void region_cb(Player *p, Region *rgn, int x, int y, int entering)

if (entering && strcmp(mapdata->RegionName(rgn), "warpregion") == 0)
{
   Target t;
   t.u.type = T_PLAYER;
   t.u.p = p;

   game->prize(&t, PRIZE_WARP, 1);
}


i88gerbils - Thu Sep 28, 2006 1:43 pm
Post subject:
Is there a better way to figure out the region other than a strcmp of the name? I had been wondering this for awhile.
Bak - Thu Sep 28, 2006 2:19 pm
Post subject:
Yes, when you initialize do mapdata->FindRegionByName and store the Region*, then just compare the pointers. However, players entering and exiting regions are rare events, so in my opinion the simplicity of a strcmp is more valuable than any speed gained by storing the Region*.
corvey - Tue Apr 10, 2007 5:34 am
Post subject:
I'm having a hard time understanding how to implement the region. I know you've given some informational links, and I read it, but still I'm confused. I'm new here so please give me a chance to learn one step at a time.

If I fly a ship into a region, I want that region to print out to the user "You are in the region" one time, and when you leave the region it will print "You are leaving the region" one time by the chat module. Some real in code examples on this will help me a great deal.

I also need to know the ObjectID # (for the picture assigned or the region assigned?) to compare with the MySQL database to see who owns that ObjectID. I do not know how to refer to or implement the format for ObjectID. This code will provide information who actually owns this region by checking it through MySQL.
Smong - Tue Apr 10, 2007 10:49 am
Post subject:
I think Bak explains it quite well in a post higher up http://forums.minegoboom.com/viewtopic.php?p=65594#65594

autowarp.c also shows the basics, but you might get confused over the chunk stuff.

Here's something I just wrote that will print region names when you enter and exit them:
Code: Show/Hide
#include "asss.h"

local void MyRegionFunc(Player *p, Region *rgn, int x, int y, int entering);

local Imodman *mm;
local Ichat *chat;
local Imapdata *mapdata;

local void MyRegionFunc(Player *p, Region *rgn, int x, int y, int entering)
{
   const char *rname = mapdata->RegionName(rgn);

   if (entering)
   {
      chat->SendMessage(p, "entering region %s", rname);
   }
   else
   {
      chat->SendMessage(p, "leaving region %s", rname);
   }
}


EXPORT int MM_regiontriggers(int action, Imodman *mm_, Arena *arena)
{
   if (action == MM_LOAD)
   {
      mm = mm_;
      chat = mm->GetInterface(I_CHAT, ALLARENAS);
      mapdata = mm->GetInterface(I_MAPDATA, ALLARENAS);
      if (!chat || !mapdata)
         return MM_FAIL;
      return MM_OK;
   }
   else if (action == MM_UNLOAD)
   {
      mm->ReleaseInterface(chat);
      mm->ReleaseInterface(mapdata);
      return MM_OK;
   }
   else if (action == MM_ATTACH)
   {
      mm->RegCallback(CB_REGION, MyRegionFunc, arena);
      return MM_OK;
   }
   else if (action == MM_DETACH)
   {
      mm->UnregCallback(CB_REGION, MyRegionFunc, arena);
      return MM_OK;
   }

   return MM_FAIL;
}

The most important line is probably:
Code: Show/Hide
      mm->RegCallback(CB_REGION, MyRegionFunc, arena);
This makes MyRegionFunc get called each time a player enters or leaves any region. One of the parameters to the function is a pointer to the region, if you look in mapdata.h you can see there are many things you can do with this pointer such as:
Code: Show/Hide
   const char *rname = mapdata->RegionName(rgn);
The region name will be whatever you named it in the map editor.

In your second problem with mysql I'm not entirely sure what you want to do. Assuming each region is a planet and you want to send an enter message saying who owns the planet you could do something like this:
Code: Show/Hide
SELECT Owner FROM SomeTable WHERE RegionName = 'some name'
SomeTable would be a table with two columns, one with player names and one with region names. 'some name' would come from mapdata->RegionName(rgn). When the query finishes you will have the name of the owner which you can then send in a message.
tcsoccerman - Tue Apr 10, 2007 5:41 pm
Post subject:
chambahs, can i use some of that coding in my zone?
corvey - Tue Apr 10, 2007 7:07 pm
Post subject:
Smong wrote:

In your second problem with mysql I'm not entirely sure what you want to do. Assuming each region is a planet and you want to send an enter message saying who owns the planet you could do something like this:
Code: Show/Hide
SELECT Owner FROM SomeTable WHERE RegionName = 'some name'
SomeTable would be a table with two columns, one with player names and one with region names. 'some name' would come from mapdata->RegionName(rgn). When the query finishes you will have the name of the owner which you can then send in a message.




Well the region name (AKA planet name) will need to be defined by the player when they first claim a planet, and if they choose to they can update that name in the database under planet options, WHEN they are in the correct region. So is it possible for the user to change the region name? That is, I don't want to define a permanent region name from the level editor, it is only a temp name until the planet name is truly declared in the database by the player.

EDIT: OK I think it can be done, I just have to look at this differently.
For example, all the regionID names will be in the database, with rows of Planetname, Owner, Fighters, etc... when the region ID is entered it will then load regionID from the database and then get the correct row for display. Right?

Thank you for writing out that region code for me Smong.
Smong - Tue Apr 10, 2007 7:21 pm
Post subject:
The regions are kind of hardcoded into each map. You can only create and name them from the map editor (so a player could open a map to find planet locations).

What I suggest is name the regions planet1, planet2, etc. Then using yet another column in a mysql table you can convert that to the planet's real name.
Code: Show/Hide
region_name | object id | planet_name | owner
------------+-----------+-------------+------
planet1     | 9600      | <unclaimed> | <none>
planet2     | 9601      | Pluto       | Mickey
...

SELECT planet_name, owner
FROM SomeTable
WHERE region_name = 'some name'

/* insert asss mysql code here
* ... */

chat->SendMessage(p, "You have landed on the planet %s owned by %s", planetname, owner)

corvey - Tue Apr 10, 2007 7:24 pm
Post subject:
LOL.. right! I couldn't get the last post edited fast enough..


Thanks for the help Smong!
All times are -5 GMT
View topic
Powered by phpBB 2.0 .0.11 © 2001 phpBB Group